2014-01-12 01:31:22 +04:00
|
|
|
---
|
|
|
|
language: Objective-C
|
|
|
|
contributors:
|
|
|
|
- ["Eugene Yagrushkin", "www.about.me/yagrushkin"]
|
|
|
|
- ["Yannick Loriot", "https://github.com/YannickL"]
|
|
|
|
- ["Levi Bostian", "https://github.com/levibostian"]
|
|
|
|
translators:
|
|
|
|
- ["Yannick Loriot", "https://github.com/YannickL"]
|
2014-01-30 11:30:28 +04:00
|
|
|
filename: LearnObjectiveC-fr.m
|
2014-01-30 10:01:30 +04:00
|
|
|
lang: fr-fr
|
2014-01-12 01:31:22 +04:00
|
|
|
---
|
|
|
|
|
2021-05-25 14:42:50 +03:00
|
|
|
L'Objective-C est un langage de programmation orienté objet réflexif principalement utilisé par Apple pour les systèmes d'exploitations macOS et iOS et leurs frameworks respectifs, Cocoa et Cocoa Touch.
|
2014-01-12 01:31:22 +04:00
|
|
|
|
2015-10-09 17:32:05 +03:00
|
|
|
```objective-c
|
2014-01-24 23:00:45 +04:00
|
|
|
// Les commentaires sur une seule ligne commencent par //
|
2014-01-12 01:31:22 +04:00
|
|
|
|
|
|
|
/*
|
2014-01-24 23:00:45 +04:00
|
|
|
Les
|
|
|
|
commentaires
|
|
|
|
multi-lignes
|
|
|
|
ressemblent
|
|
|
|
à
|
|
|
|
ceci
|
2014-01-12 01:31:22 +04:00
|
|
|
*/
|
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
// #import permet d'importer les en-têtes d'autres fichiers
|
2014-01-12 01:31:22 +04:00
|
|
|
// Utilisez <> pour importer des fichiers globaux (en général des frameworks)
|
|
|
|
// Utilisez "" pour importer des fichiers locaux (du projet)
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
#import "MaClasse.h"
|
|
|
|
|
2021-05-25 14:42:50 +03:00
|
|
|
// Si vous activez les modules dans les projets iOS >= 7 ou OS X >= 10.9
|
2014-01-24 23:00:45 +04:00
|
|
|
// dans Xcode 5, vous pouvez importer les frameworks comme cela :
|
2014-01-12 01:31:22 +04:00
|
|
|
@import Foundation;
|
|
|
|
|
|
|
|
// Le point d'entrée de votre programme est une fonction qui s'appelle main
|
2014-01-24 23:00:45 +04:00
|
|
|
// et qui retourne un entier comme type
|
2014-01-12 01:31:22 +04:00
|
|
|
int main (int argc, const char * argv[])
|
|
|
|
{
|
|
|
|
// Créer un groupe de libération automatique de la mémoire pour l'ensemble
|
|
|
|
// du programme
|
|
|
|
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
|
|
|
// Si vous utilisez le comptage de référence automatique (ARC), utilisez
|
|
|
|
// @autoreleasepool à la place :
|
|
|
|
@autoreleasepool {
|
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
// NSLog() permet d'afficher une chaine de caractères dans la console
|
2014-01-12 01:31:22 +04:00
|
|
|
// Affiche la chaine de caractères "Bonjour Tous Le Monde !"
|
|
|
|
NSLog(@"Bonjour tous le Monde !");
|
|
|
|
|
|
|
|
///////////////////////////////////////
|
|
|
|
// Les Types & Les Variables
|
|
|
|
///////////////////////////////////////
|
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
// La déclaration de primitive
|
2014-01-12 01:31:22 +04:00
|
|
|
int maPrimitive1 = 1;
|
|
|
|
long maPrimitive2 = 234554664565;
|
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
// La déclaration d'objet
|
|
|
|
// Il faut mettre un astérisque devant la déclaration d'objet fortement typé
|
2014-01-12 01:31:22 +04:00
|
|
|
MaClasse *monObject1 = nil; // Typage fort
|
|
|
|
id monObject2 = nil; // Typage faible
|
2014-01-25 01:07:09 +04:00
|
|
|
// 'description' est une méthode qui permet de retourner un aperçut de l'objet sous forme textuelle
|
2014-01-24 23:00:45 +04:00
|
|
|
// La méthode 'description' est appelée par défaut quand on utilise le paramètre '%@'
|
2014-01-12 01:31:22 +04:00
|
|
|
NSLog(@"%@ and %@", monObject1, [monObject2 description]); // Affiche "(null) et (null)"
|
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
// Les chaines de caractères
|
2014-01-12 01:31:22 +04:00
|
|
|
NSString *chaineMonde = @"Monde";
|
|
|
|
NSLog(@"Bonjour tous le %@ !", chaineMonde); // affiche => "Bonjour Tous Le Monde !"
|
|
|
|
// NSMutableString est une chaine mutable
|
|
|
|
NSMutableString *chaineMutable = [NSMutableString stringWithString:@"Bonjour tous le"];
|
|
|
|
[chaineMutable appendString:@" Monde !"];
|
|
|
|
NSLog(@"%@", chaineMutable); // affiche => "Bonjour Tous Le Monde !"
|
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
// Les caractères
|
2014-01-12 01:31:22 +04:00
|
|
|
NSNumber *laLettreZSousFormeDeNombre = @'Z';
|
|
|
|
char laLettreZ = [laLettreZSousFormeDeNombre charValue]; // ou 'Z'
|
|
|
|
NSLog(@"%c", laLettreZ);
|
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
// Les nombres
|
2014-01-12 01:31:22 +04:00
|
|
|
NSNumber *nombreQuaranteDeux = @42;
|
|
|
|
int quaranteDeux = [nombreQuaranteDeux intValue]; // ou 42
|
|
|
|
NSLog(@"%i", quaranteDeux);
|
|
|
|
|
|
|
|
NSNumber *nombreQuaranteDeuxnonSigne = @42U;
|
|
|
|
unsigned int quaranteDeuxnonSigne = [nombreQuaranteDeuxnonSigne unsignedIntValue];
|
|
|
|
NSLog(@"%u", fortyTwoUnsigned);
|
|
|
|
|
|
|
|
NSNumber *nombreQuaranteDeuxCourt = [NSNumber numberWithShort:42];
|
|
|
|
short quaranteDeuxCourt = [nombreQuaranteDeuxCourt shortValue]; // ou 42
|
|
|
|
NSLog(@"%hi", fortyTwoShort);
|
|
|
|
|
|
|
|
NSNumber *nombreQuaranteDeuxLong = @42L;
|
|
|
|
long quaranteDeuxLong = [nombreQuaranteDeuxLong longValue]; // ou 42
|
|
|
|
NSLog(@"%li", fortyTwoLong);
|
|
|
|
|
2014-01-25 01:07:09 +04:00
|
|
|
// Les nombres flottants
|
|
|
|
NSNumber *nombrePiFlottant = @3.141592654F;
|
|
|
|
float piFlottant = [nombrePiFlottant floatValue]; // ou 3.141592654f
|
|
|
|
NSLog(@"%f", piFlottant); // affiche => 3.141592654
|
|
|
|
NSLog(@"%5.2f", piFlottant); // affiche => " 3.14"
|
2014-01-12 01:31:22 +04:00
|
|
|
|
|
|
|
NSNumber *nombrePiDouble = @3.1415926535;
|
|
|
|
double piDouble = [nombrePiDouble doubleValue]; // ou 3.1415926535
|
|
|
|
NSLog(@"%f", piDouble);
|
|
|
|
NSLog(@"%4.2f", piDouble); // affiche => "3.14"
|
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
// NSDecimalNumber est une classe pour avoir plus de précision sur les nombres
|
2014-01-25 01:07:09 +04:00
|
|
|
// flottants et les doubles
|
2014-01-12 01:31:22 +04:00
|
|
|
NSDecimalNumber *decNumUn = [NSDecimalNumber decimalNumberWithString:@"10.99"];
|
|
|
|
NSDecimalNumber *decNumDeux = [NSDecimalNumber decimalNumberWithString:@"5.002"];
|
2014-01-25 01:07:09 +04:00
|
|
|
// NSDecimalNumber ne permet pas d'utiliser les opérations standards (+, -, *, /)
|
|
|
|
// Il faut utiliser les méthodes suivantes à la place :
|
2014-01-12 01:31:22 +04:00
|
|
|
[decNumUn decimalNumberByAdding:decNumDeux];
|
|
|
|
[decNumUn decimalNumberBySubtracting:decNumDeux];
|
|
|
|
[decNumUn decimalNumberByMultiplyingBy:decNumDeux];
|
|
|
|
[decNumUn decimalNumberByDividingBy:decNumDeux];
|
2014-01-24 23:00:45 +04:00
|
|
|
NSLog(@"%@", decNumUn); // affiche => 10.99 comme NSDecimalNumber est immuable
|
2014-01-12 01:31:22 +04:00
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
// Les booléens
|
2014-01-12 01:31:22 +04:00
|
|
|
NSNumber *ouiNumber = @YES;
|
|
|
|
NSNumber *nonNumber = @NO;
|
|
|
|
// ou
|
|
|
|
BOOL ouiBool = YES;
|
|
|
|
BOOL nonBool = NO;
|
|
|
|
NSLog(@"%i", ouiBool); // affiche => 1
|
|
|
|
|
|
|
|
// Les listes
|
2014-01-24 23:00:45 +04:00
|
|
|
// Une liste peut contenir uniquement des objets
|
2014-01-12 01:31:22 +04:00
|
|
|
NSArray *uneListe = @[@1, @2, @3, @4];
|
|
|
|
NSNumber *troisiemeNombre = uneListe[2];
|
|
|
|
NSLog(@"Troisième nombre = %@", troisiemeNombre); // affiche "Troisième nombre = 3"
|
2014-01-24 23:00:45 +04:00
|
|
|
// NSMutableArray est une version mutable de NSArray
|
2014-01-25 01:07:09 +04:00
|
|
|
// Cela permet de modifier la liste en ajoutant de nouveaux éléments et en supprimant ou
|
|
|
|
// changeant de place des objets déjà présent
|
2014-01-24 23:00:45 +04:00
|
|
|
// C'est très pratique, mais pas aussi performant que l'utilisation de la classe NSArray
|
2014-01-12 01:31:22 +04:00
|
|
|
NSMutableArray *listeMutable = [NSMutableArray arrayWithCapacity:2];
|
|
|
|
[listeMutable addObject:@"Bonjour tous le"];
|
|
|
|
[listeMutable addObject:@"Monde"];
|
|
|
|
[listeMutable removeObjectAtIndex:0];
|
|
|
|
NSLog(@"%@", [listeMutable objectAtIndex:0]); // affiche => "Monde"
|
|
|
|
|
|
|
|
// Les dictionnaires
|
2014-01-25 01:07:09 +04:00
|
|
|
// Un dictionnaire est un ensemble de clés : valeurs
|
2014-01-12 01:31:22 +04:00
|
|
|
NSDictionary *unDictionnaire = @{ @"cle1" : @"valeur1", @"cle2" : @"valeur2" };
|
|
|
|
NSObject *valeur = unDictionnaire[@"Une clé"];
|
|
|
|
NSLog(@"Objet = %@", valeur); // affiche "Objet = (null)"
|
2014-01-24 23:00:45 +04:00
|
|
|
// NSMutableDictionary est un dictionnaire mutable, c-à-d que l'on peut modifier
|
2014-01-12 01:31:22 +04:00
|
|
|
NSMutableDictionary *dictionnaireMutable = [NSMutableDictionary dictionaryWithCapacity:2];
|
|
|
|
[dictionnaireMutable setObject:@"valeur1" forKey:@"cle1"];
|
|
|
|
[dictionnaireMutable setObject:@"valeur2" forKey:@"cle2"];
|
|
|
|
[dictionnaireMutable removeObjectForKey:@"cle1"];
|
|
|
|
|
|
|
|
// Les ensembles
|
2014-01-25 01:07:09 +04:00
|
|
|
// Un ensemble ne peut contenir de duplicatas contrairement aux NSArray
|
2014-01-12 01:31:22 +04:00
|
|
|
NSSet *ensemble = [NSSet setWithObjects:@"Salut", @"Salut", @"Monde", nil];
|
2014-01-24 23:00:45 +04:00
|
|
|
NSLog(@"%@", ensemble); // affiche => {(Salut, Monde)} (Pas forcément dans le même ordre)
|
2014-01-12 01:31:22 +04:00
|
|
|
// NSMutableSet est un ensemble mutable
|
|
|
|
NSMutableSet *ensembleMutable = [NSMutableSet setWithCapacity:2];
|
|
|
|
[ensembleMutable addObject:@"Salut"];
|
|
|
|
[ensembleMutable addObject:@"Salut"];
|
|
|
|
NSLog(@"%@", ensembleMutable); // affiche => {(Salut)}
|
|
|
|
|
|
|
|
///////////////////////////////////////
|
2014-01-24 23:00:45 +04:00
|
|
|
// Les Operateurs
|
2014-01-12 01:31:22 +04:00
|
|
|
///////////////////////////////////////
|
|
|
|
|
2014-01-25 01:07:09 +04:00
|
|
|
// Les opérateurs sont pareil qu'en C
|
2014-01-12 01:31:22 +04:00
|
|
|
// Par exemple :
|
|
|
|
2 + 5; // => 7
|
|
|
|
4.2f + 5.1f; // => 9.3f
|
|
|
|
3 == 2; // => 0 (NO)
|
|
|
|
3 != 2; // => 1 (YES)
|
|
|
|
1 && 1; // => 1 (et logique)
|
|
|
|
0 || 1; // => 1 (ou logique)
|
|
|
|
~0x0F; // => 0xF0 (négation bit à bit)
|
|
|
|
0x0F & 0xF0; // => 0x00 (et bit à bit)
|
2014-01-25 01:07:09 +04:00
|
|
|
0x01 << 1; // => 0x02 (décalage à gauche (par 1))
|
2014-01-12 01:31:22 +04:00
|
|
|
|
|
|
|
///////////////////////////////////////
|
2014-01-25 01:07:09 +04:00
|
|
|
// Les Structures de Contrôle
|
2014-01-12 01:31:22 +04:00
|
|
|
///////////////////////////////////////
|
|
|
|
|
2014-01-25 01:07:09 +04:00
|
|
|
// Structure "Si-Sinon" (If-Else)
|
2014-01-12 01:31:22 +04:00
|
|
|
if (NO)
|
|
|
|
{
|
|
|
|
NSLog(@"Je ne suis jamais affiché");
|
|
|
|
} else if (0)
|
|
|
|
{
|
|
|
|
NSLog(@"Je ne suis jamais affiché aussi");
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
NSLog(@"Je suis affiché");
|
|
|
|
}
|
|
|
|
|
2014-01-25 01:07:09 +04:00
|
|
|
// Structure "Selon" (Switch)
|
2014-01-12 01:31:22 +04:00
|
|
|
switch (2)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
NSLog(@"Je ne suis jamais affiché");
|
|
|
|
} break;
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
NSLog(@"Je ne suis jamais affiché aussi");
|
|
|
|
} break;
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
NSLog(@"Je suis affiché");
|
|
|
|
} break;
|
|
|
|
}
|
|
|
|
|
2014-01-25 01:07:09 +04:00
|
|
|
// Structure de boucle "Tant Que" (While)
|
2014-01-12 01:31:22 +04:00
|
|
|
int ii = 0;
|
|
|
|
while (ii < 4)
|
|
|
|
{
|
2014-01-24 23:00:45 +04:00
|
|
|
NSLog(@"%d,", ii++); // ii++ incrémente ii après avoir utilisé sa valeur
|
2014-01-12 01:31:22 +04:00
|
|
|
} // => affiche "0,"
|
|
|
|
// "1,"
|
|
|
|
// "2,"
|
|
|
|
// "3,"
|
|
|
|
|
2014-01-25 01:07:09 +04:00
|
|
|
// Structure de boucle "Pour" (For)
|
2014-01-12 01:31:22 +04:00
|
|
|
int jj;
|
|
|
|
for (jj=0; jj < 4; jj++)
|
|
|
|
{
|
|
|
|
NSLog(@"%d,", jj);
|
|
|
|
} // => affiche "0,"
|
|
|
|
// "1,"
|
|
|
|
// "2,"
|
|
|
|
// "3,"
|
|
|
|
|
2014-01-25 01:07:09 +04:00
|
|
|
// Structure de boucle "Pour Chaque" (Foreach)
|
2014-01-12 01:31:22 +04:00
|
|
|
NSArray *valeurs = @[@0, @1, @2, @3];
|
|
|
|
for (NSNumber *valeur in valeurs)
|
|
|
|
{
|
|
|
|
NSLog(@"%@,", valeur);
|
|
|
|
} // => affiche "0,"
|
|
|
|
// "1,"
|
|
|
|
// "2,"
|
|
|
|
// "3,"
|
|
|
|
|
2014-01-25 01:07:09 +04:00
|
|
|
// Structure "Essayer-Attraper-Finalement" (Try-Catch-Finally)
|
2014-01-12 01:31:22 +04:00
|
|
|
@try
|
|
|
|
{
|
|
|
|
@throw [NSException exceptionWithName:@"FileNotFoundException"
|
|
|
|
reason:@"Fichier non trouvé" userInfo:nil];
|
|
|
|
} @catch (NSException * e)
|
|
|
|
{
|
2014-01-24 23:00:45 +04:00
|
|
|
NSLog(@"Une exception est survenue : %@", e);
|
2014-01-12 01:31:22 +04:00
|
|
|
} @finally
|
|
|
|
{
|
|
|
|
NSLog(@"Finalement");
|
2014-01-24 23:00:45 +04:00
|
|
|
} // => affiche "Une exception est survenue : Fichier non trouvé"
|
2014-01-12 01:31:22 +04:00
|
|
|
// "Finalement"
|
|
|
|
|
|
|
|
///////////////////////////////////////
|
2014-01-24 23:00:45 +04:00
|
|
|
// Les Objets
|
2014-01-12 01:31:22 +04:00
|
|
|
///////////////////////////////////////
|
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
// Définis et créé une instance d'objet en allouant un espace mémoire puis en
|
|
|
|
// l'initialisant. Un objet n'est pas complétement fonctionnel tant que les deux
|
|
|
|
// étapes précédentes ne sont pas terminées
|
2014-01-12 01:31:22 +04:00
|
|
|
MaClass *monObjet = [[MaClass alloc] init];
|
|
|
|
|
2014-01-25 01:07:09 +04:00
|
|
|
// L'Objet en Objective-C est basé sur le principe d'envoie de message et non sur
|
|
|
|
// celui d'appel de méthode comme la plupart des autres langages
|
|
|
|
// C'est un détail important car cela veut dire que l'on peut envoyer un message
|
|
|
|
// à un objet qui ne possède pas la méthode demandée sans aucune incidence sur le
|
|
|
|
// fonctionnement du programme (aucune exception ne sera levée)
|
2014-01-12 01:31:22 +04:00
|
|
|
[myObject instanceMethodWithParameter:@"Steve Jobs"];
|
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
// Nettoie la mémoire qui a été utilisée dans le programme
|
2014-01-12 01:31:22 +04:00
|
|
|
[pool drain];
|
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
// Fin de l'@autoreleasepool
|
2014-01-12 01:31:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Fin du programme
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////
|
2014-01-24 23:00:45 +04:00
|
|
|
// Les Classes et Les Fonctions
|
2014-01-12 01:31:22 +04:00
|
|
|
///////////////////////////////////////
|
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
// Déclaration d'une classe dans un en-tête de fichier (MaClasse.h) :
|
|
|
|
// La déclaration d'une classe en Objective-C commence par la déclaration de son interface :
|
|
|
|
// @interface NomDeLaClasse : NomDeLaClasseParent <ListeDesProtocoles>
|
2014-01-12 01:31:22 +04:00
|
|
|
// {
|
2014-01-25 01:07:09 +04:00
|
|
|
// type nom; // Déclaration d'une variable;
|
2014-01-12 01:31:22 +04:00
|
|
|
// }
|
2014-01-25 01:07:09 +04:00
|
|
|
// @property type nom; // Déclaration d'une propriété
|
|
|
|
// -/+ (type)nomDeLaMethode; // Déclaration d'une methode
|
2014-01-24 23:00:45 +04:00
|
|
|
// @end // Termine la déclaration
|
|
|
|
// NSObject est la classe de base (super classe) en Objective-C
|
2014-01-12 01:31:22 +04:00
|
|
|
@interface MaClasse : NSObject <MonProtocole>
|
|
|
|
{
|
2014-01-24 23:00:45 +04:00
|
|
|
int nombre; // Accès protégé par défaut (équivalent à '@protected int nombre;')
|
2014-01-12 01:31:22 +04:00
|
|
|
@private id donnee; // Accès privé (il est plus pratique de le faire dans l'implémentation)
|
|
|
|
NSString *nom;
|
|
|
|
}
|
2014-01-25 01:07:09 +04:00
|
|
|
// Les propriétés permettent de générer les accésseurs/affecteurs publiques à la compilation
|
2014-01-24 23:00:45 +04:00
|
|
|
// Par défaut, le nom de l'affecteur est la chaine 'set' suivi par le nom de la @property
|
|
|
|
@property int propInt; // Nom de l'affecteur = 'setPropInt'
|
2014-01-12 01:31:22 +04:00
|
|
|
@property (copy) id copyId; // (copy) => Copie l'objet pendant l'affectation
|
|
|
|
// (readonly) => Ne peut pas affecté la variable en dehors de l'@interface
|
2014-01-24 23:00:45 +04:00
|
|
|
// Il faut utiliser le mot clé '@synthesize' dans l'@implementation pour créer l'accésseur
|
2014-01-12 01:31:22 +04:00
|
|
|
@property (readonly) NSString *roString;
|
2014-01-24 23:00:45 +04:00
|
|
|
// Vous pouvez aussi personnaliser les noms des accésseurs ou des affecteurs
|
2014-01-12 01:31:22 +04:00
|
|
|
@property (getter=longeurGet, setter=longeurSet:) int longeur;
|
|
|
|
|
|
|
|
// Methodes
|
2014-01-24 23:00:45 +04:00
|
|
|
+/- (TypeDeRetour)signatureDeLaMethode:(TypeDuParametre *)nomDuParametre;
|
2014-01-12 01:31:22 +04:00
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
// '+' signifie que c'est une méthode de classe (statique) :
|
2014-01-12 01:31:22 +04:00
|
|
|
+ (NSString *)methodeDeClasse;
|
|
|
|
+ (MaClasse *)maClasseDepuisLaHauteur:(NSNumber *)hauteurParDefaut;
|
|
|
|
|
2014-01-24 23:19:22 +04:00
|
|
|
// '-' pour les méthodes d'instances :
|
2014-01-12 01:31:22 +04:00
|
|
|
- (NSString *)methodeInstanceAvecUnParametre:(NSString *)string;
|
|
|
|
- (NSNumber *)methodeInstanceAvecUnParametre:(NSString*)string puisUnDeuxieme:(NSNumber *)number;
|
|
|
|
|
|
|
|
// Contructeur avec des arguments :
|
|
|
|
- (id)initAvecDistance:(int)distanceParDefault;
|
2014-01-24 23:00:45 +04:00
|
|
|
// Les méthodes en Objective-C sont très descriptives
|
2014-01-12 01:31:22 +04:00
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
@end // Fin de l'interface
|
2014-01-12 01:31:22 +04:00
|
|
|
|
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
// Voici un exemple d'utilisation de MaClasse
|
2014-01-12 01:31:22 +04:00
|
|
|
MaClasse *maClasse = [[MaClasse alloc] init]; // créer une instance de MaClasse
|
|
|
|
[maClasse setNombre:10];
|
|
|
|
NSLog(@"%d", [maClasse nombre]); // affiche => 10
|
|
|
|
[myClass longeurSet:32];
|
|
|
|
NSLog(@"%i", [maClasse longeurGet]); // affiche => 32
|
|
|
|
// Pour des raisons pratiques vous pouvez aussi utiliser la notation en point pour accéder aux
|
|
|
|
// variables d'instances :
|
|
|
|
maClasse.nombre = 45;
|
|
|
|
NSLog(@"%i", maClasse.nombre); // maClasse => 45
|
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
// Pour appeler une méthode de classe :
|
2014-01-12 01:31:22 +04:00
|
|
|
NSString *s1 = [MaClasse methodeDeClasse];
|
|
|
|
MaClasse *m2 = [MaClasse maClasseDepuisLaHauteur:38];
|
|
|
|
|
2014-01-24 23:00:45 +04:00
|
|
|
// Pour appeler une méthode d'instance :
|
2014-01-12 01:31:22 +04:00
|
|
|
MaClasse *maClasse = [[MaClasse alloc] init]; // Créer une instance de MaClasse
|
|
|
|
NSString *stringDepuisUneInstanceDeMethode = [maClasse methodeInstanceAvecUnParametre:@"Salut"];
|
|
|
|
|
2014-01-25 01:07:09 +04:00
|
|
|
// Les sélecteurs sont un moyen de décrire les méthodes dynamiquement
|
2014-01-24 23:00:45 +04:00
|
|
|
// Ils sont utilisés pour appeler des méthodes de classe et avoir des pointeurs de fonctions
|
|
|
|
// facilement manipulable
|
|
|
|
// SEL est un type de donnée et @selector retourne un selecteur à partir d'un nom de methode
|
2014-01-12 01:31:22 +04:00
|
|
|
SEL selecteur = @selector(methodeInstanceAvecUnParametre:puisUnDeuxieme:);
|
2014-01-24 23:00:45 +04:00
|
|
|
if ([maClasse respondsToSelector:selecteur]) { // Vérifie si la classe possède la méthode
|
|
|
|
// Met les arguments de la méthode dans un seul objet pour l'envoyer via la fonction
|
2014-01-12 01:31:22 +04:00
|
|
|
// performSelector:withObject:
|
|
|
|
NSArray *arguments = [NSArray arrayWithObjects:@"Hello", @4, nil];
|
2014-01-24 23:00:45 +04:00
|
|
|
[myClass performSelector:selectorVar withObject:arguments]; // Appele la méthode via le sélecteur
|
2014-01-24 23:19:22 +04:00
|
|
|
}
|
|
|
|
else {
|
2014-01-24 23:00:45 +04:00
|
|
|
// NSStringFromSelector() retourne une chaine de caractères à partir d'un sélecteur
|
2014-01-12 01:31:22 +04:00
|
|
|
NSLog(@"MaClasse ne possède pas de méthode : %@", NSStringFromSelector(selecteur));
|
|
|
|
}
|
|
|
|
|
2014-01-24 23:19:22 +04:00
|
|
|
// Le fichier d'implémentation de la classe MaClasse (MaClasse.m) doit commencer comme ceci :
|
2014-01-12 01:31:22 +04:00
|
|
|
@implementation MaClasse {
|
2014-01-25 01:07:09 +04:00
|
|
|
long distance; // Variable d'instance privée (équivalent à @private dans l'interface)
|
2014-01-12 01:31:22 +04:00
|
|
|
NSNumber hauteur;
|
|
|
|
}
|
|
|
|
|
2014-01-24 23:19:22 +04:00
|
|
|
// Pour accéder à une variable depuis l'implémentation on peut utiliser le _ (tiret bas) devant le nom
|
2014-01-12 01:31:22 +04:00
|
|
|
// de la variable :
|
|
|
|
_nombre = 5;
|
2014-01-25 01:07:09 +04:00
|
|
|
// Accès d'une variable définie dans le fichier d'implémentation :
|
2014-01-12 01:31:22 +04:00
|
|
|
distance = 18;
|
2014-01-25 01:07:09 +04:00
|
|
|
// Pour utiliser la variable définie par l'intermédiaire de @property, il faut utiliser @synthesize
|
|
|
|
// qui permet de créer les affecteurs et les accésseurs correspondants :
|
2014-01-24 23:19:22 +04:00
|
|
|
@synthesize roString = _roString; // _roString est maintenant disponible dans l'implementation
|
2014-01-12 01:31:22 +04:00
|
|
|
|
2014-01-25 01:07:09 +04:00
|
|
|
// A l'inverse dela méthode 'init' qui est appelée lors de la création d'un objet, la fonction
|
2014-01-24 23:19:22 +04:00
|
|
|
// 'dealloc' est appelée quand l'objet est supprimé
|
2014-01-12 01:31:22 +04:00
|
|
|
- (void)dealloc
|
|
|
|
{
|
2014-01-24 23:19:22 +04:00
|
|
|
[hauteur release]; // Si vous n'utilisez pas ARC, pensez bien à supprimer l'objet
|
|
|
|
[super dealloc]; // et à appeler la méthode 'dealloc' de la classe parent
|
2014-01-12 01:31:22 +04:00
|
|
|
}
|
|
|
|
|
2014-01-25 01:07:09 +04:00
|
|
|
// Les constructeurs sont des fonctions qui permettent d'instancier un objet
|
|
|
|
// 'init' est le constructeur par défaut en Objective-C
|
2014-01-12 01:31:22 +04:00
|
|
|
- (id)init
|
|
|
|
{
|
2014-01-13 01:43:53 +04:00
|
|
|
if ((self = [super init])) // 'super' est utilisé pour appeler la méthode de la classe parent
|
2014-01-12 01:31:22 +04:00
|
|
|
{
|
2014-01-25 01:07:09 +04:00
|
|
|
self.count = 1; // 'self' permet d'appeler la méthode de l'instance courante
|
2014-01-12 01:31:22 +04:00
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
2014-01-13 01:43:53 +04:00
|
|
|
|
2014-01-25 01:07:09 +04:00
|
|
|
// Vous pouvez aussi créer des constructeurs avec des arguments
|
2014-01-24 23:19:22 +04:00
|
|
|
// Attention : chaque nom de constructeur doit absolument commencer par 'init'
|
2014-01-13 01:43:53 +04:00
|
|
|
- (id)initAvecUneDistance:(int)distanceParDefault
|
2014-01-12 01:31:22 +04:00
|
|
|
{
|
2014-01-13 01:43:53 +04:00
|
|
|
if ((self = [super init]))
|
|
|
|
{
|
|
|
|
distance = distanceParDefault;
|
|
|
|
return self;
|
|
|
|
}
|
2014-01-12 01:31:22 +04:00
|
|
|
}
|
|
|
|
|
2014-01-24 23:19:22 +04:00
|
|
|
// Implémentation d'une méthode de classe
|
2014-01-13 01:43:53 +04:00
|
|
|
+ (NSString *)methodDeClasse
|
2014-01-12 01:31:22 +04:00
|
|
|
{
|
|
|
|
return [[self alloc] init];
|
|
|
|
}
|
|
|
|
|
2014-01-13 01:43:53 +04:00
|
|
|
+ (MaClasse *)maClasseDepuisUneHauteur:(NSNumber *)hauteurParDefaut
|
2014-01-12 01:31:22 +04:00
|
|
|
{
|
2014-01-13 01:43:53 +04:00
|
|
|
hauteur = hauteurParDefaut;
|
2014-01-12 01:31:22 +04:00
|
|
|
return [[self alloc] init];
|
|
|
|
}
|
|
|
|
|
2014-01-24 23:19:22 +04:00
|
|
|
// Implémentation d'une méthode d'instance
|
2014-01-13 01:43:53 +04:00
|
|
|
- (NSString *)methodeInstanceAvecUnParametre:(NSString *)string
|
2014-01-12 01:31:22 +04:00
|
|
|
{
|
2014-01-24 23:00:45 +04:00
|
|
|
return @"Ma chaine de caractère";
|
2014-01-12 01:31:22 +04:00
|
|
|
}
|
|
|
|
|
2014-01-13 01:43:53 +04:00
|
|
|
- (NSNumber *)methodeInstanceAvecUnParametre:(NSString*)string puisUnDeuxieme:(NSNumber *)number
|
2014-01-12 01:31:22 +04:00
|
|
|
{
|
|
|
|
return @42;
|
|
|
|
}
|
|
|
|
|
2014-01-24 23:19:22 +04:00
|
|
|
// Pour créer une méthode privée, il faut la définir dans l'implementation et non pas dans
|
|
|
|
// l'interface
|
2014-01-13 01:43:53 +04:00
|
|
|
- (NSNumber *)methodePrivee
|
|
|
|
{
|
2014-01-12 01:31:22 +04:00
|
|
|
return @72;
|
|
|
|
}
|
|
|
|
|
2014-01-13 01:43:53 +04:00
|
|
|
[self methodePrivee]; // Appel de la méthode privée
|
|
|
|
|
2014-01-24 23:19:22 +04:00
|
|
|
// Implémentation d'une méthode qui est déclarée dans <MonProtocole>
|
2014-01-13 01:43:53 +04:00
|
|
|
- (void)methodeDuProtocole
|
2014-01-12 01:31:22 +04:00
|
|
|
{
|
2014-01-13 01:43:53 +04:00
|
|
|
// expressions
|
2014-01-12 01:31:22 +04:00
|
|
|
}
|
|
|
|
|
2014-01-13 01:43:53 +04:00
|
|
|
@end // Fin de l'implémentation
|
2014-01-12 01:31:22 +04:00
|
|
|
|
|
|
|
/*
|
2014-01-25 01:07:09 +04:00
|
|
|
* Un protocole déclare des méthodes et propriétés que chaque implémentation doit avoir afin de se
|
|
|
|
* conformer à celui-ci
|
2014-01-13 01:43:53 +04:00
|
|
|
* Un protocole n'est pas une classe, c'est juste une interface
|
2014-01-12 01:31:22 +04:00
|
|
|
*/
|
2014-01-13 01:43:53 +04:00
|
|
|
@protocol MonProtocole
|
|
|
|
- (void)methodeDuProtocole;
|
2014-01-12 01:31:22 +04:00
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////
|
2014-01-21 01:42:23 +04:00
|
|
|
// Gestion de la mémoire
|
2014-01-12 01:31:22 +04:00
|
|
|
///////////////////////////////////////
|
|
|
|
/*
|
2014-01-25 01:07:09 +04:00
|
|
|
À chaque fois qu'un objet est créé dans l'application, un bloc mémoire doit être alloué.
|
|
|
|
Quand l'application en a fini avec cet objet, la mémoire doit être libérée afin d'éviter les fuites
|
|
|
|
mémoires
|
|
|
|
Il n'y a pas de ramasse-miettes en Objective-C contrairement à Java par exemple. La gestion de la
|
|
|
|
mémoire repose sur le comptage de référence qui, pour chaque objet, assigne un compteur qui permet
|
|
|
|
de connaitre le nombre de référence qui l'utilise.
|
2014-01-24 23:19:22 +04:00
|
|
|
|
|
|
|
Le principe est le suivant :
|
|
|
|
Lorsque l'objet est créé, le compteur est initialisé à 1. Quand une instance détient un objet, le
|
2014-01-25 01:07:09 +04:00
|
|
|
compteur est incrémenté de un. Quand l'objet est libéré, le compteur est décrémenté de un. Au moment
|
|
|
|
où le compteur arrive à zéro, l'objet est supprimé de la mémoire
|
2014-01-21 01:42:23 +04:00
|
|
|
|
|
|
|
Une bonne pratique à suivre quand on travaille avec des objets est la suivante :
|
2014-01-24 21:36:30 +04:00
|
|
|
(1) créer un objet, (2) utiliser l'objet, (3) supprimer l'objet de la mémoire
|
2014-01-12 01:31:22 +04:00
|
|
|
*/
|
|
|
|
|
2014-01-21 01:42:23 +04:00
|
|
|
MaClasse *classeVar = [MyClass alloc]; // 'alloc' incrémente le compteur de référence
|
|
|
|
[classeVar release]; // Décrémente le compteur de rérence
|
|
|
|
// 'retain' incrémente le compteur de référence
|
2014-01-25 01:07:09 +04:00
|
|
|
// Si 'classeVar' est libéré, l'objet reste en mémoire car le compteur de référence est non nul
|
2014-01-21 01:42:23 +04:00
|
|
|
MaClasse *nouvelleVar = [classVar retain];
|
2014-01-25 01:07:09 +04:00
|
|
|
[classeVar autorelease]; // Supprime l'appartenance de l'objet à la fin du bloc
|
2014-01-12 01:31:22 +04:00
|
|
|
|
2014-01-25 01:07:09 +04:00
|
|
|
// Les @property peuvent utiliser 'retain' et 'assign'
|
2014-01-21 01:42:23 +04:00
|
|
|
@property (retain) MaClasse *instance; // Libère l'ancienne valeur et retient la nouvelle
|
|
|
|
@property (assign) NSSet *set; // Pointeur vers la valeur sans retenir/libérer l'ancienne valeur
|
2014-01-12 01:31:22 +04:00
|
|
|
|
|
|
|
// Automatic Reference Counting (ARC)
|
2014-01-25 01:07:09 +04:00
|
|
|
// La gestion de la mémoire étant pénible, depuis iOS 4 et Xcode 4.2, Apple a introduit le comptage de
|
|
|
|
// référence automatique (Automatic Reference Counting en anglais)
|
|
|
|
// ARC est une fonctionnalité du compilateur qui permet d'ajouter les 'retain', 'release' et 'autorelease'
|
|
|
|
// automatiquement. Cela veut dire que lorsque vous utilisez ARC vous ne devez plus utiliser ces mot-clés
|
2014-01-24 21:36:30 +04:00
|
|
|
MaClasse *arcMaClasse = [[MaClasse alloc] init];
|
|
|
|
// ... code utilisant arcMaClasse
|
2014-01-25 01:07:09 +04:00
|
|
|
// Sans ARC, vous auriez dû appeler [arcMaClasse release] après avoir utilisé l'objet. Mais avec ARC
|
|
|
|
// activé il n'est plus nécessaire de le faire car le compilateur ajoutera l'expréssion automatiquement
|
|
|
|
// pour vous
|
2014-01-24 21:36:30 +04:00
|
|
|
|
|
|
|
// Les mots clés 'assign' et 'retain', avec ARC sont respectivement remplacé par 'weak' et 'strong'
|
2014-01-25 01:07:09 +04:00
|
|
|
@property (weak) MaClasse *weakVar; // 'weak' ne retient pas l'objet. Si le compteur de référence
|
|
|
|
// descend à zero, weakVar sera automatiquement mis à nil
|
|
|
|
@property (strong) MaClasse *strongVar; // 'strong' prend possession de l'objet comme le ferait avec
|
|
|
|
// le mot-clé 'retain'
|
|
|
|
|
|
|
|
// Pour l'instanciation des variables (en dehors de @property), vous pouvez utiliser les instructions
|
|
|
|
// suivantes :
|
|
|
|
__strong NSString *strongString; // Par défaut. La variable est retenue en mémoire jusqu'à la fin
|
|
|
|
// de sa portée
|
|
|
|
__weak NSSet *weakSet; // Maintient une référence vers l'objet sans incrémenter son compteur de référence :
|
|
|
|
// Lorsque l'objet sera supprimé, weakSet sera mis à nil automatiquement
|
|
|
|
__unsafe_unretained NSArray *unsafeArray; // Comme __weak, mais la variable n'est pas mis à nil quand
|
|
|
|
// l'objet est supprimé
|
2014-01-12 01:31:22 +04:00
|
|
|
|
|
|
|
```
|
2016-02-13 10:04:31 +03:00
|
|
|
|
2014-01-21 01:42:23 +04:00
|
|
|
## Lectures Complémentaires
|
2014-01-12 01:31:22 +04:00
|
|
|
|
|
|
|
[La Page Wikipedia de l'Objective-C](http://fr.wikipedia.org/wiki/Objective-C)
|
|
|
|
|
2014-01-24 21:36:30 +04:00
|
|
|
[iOS pour les écoliers : Votre première app iOS](http://www.raywenderlich.com/fr/39272/ios-pour-les-ecoliers-votre-premiere-app-ios-partie-12)
|
2014-01-12 01:31:22 +04:00
|
|
|
|
2014-01-30 10:01:30 +04:00
|
|
|
[Programming with Objective-C. Apple PDF book](https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/ProgrammingWithObjectiveC.pdf)
|