Aide-mémoire
(Fourre-tout) Objective-C:
Pour exécuter son application, cliquez simplement sur "run". Ah bon, ce n'est pas aussi simple??? :) Alors regardez la page des certificats.
Fonctions:
//Exemple1:
// A mettre dans le header (fichier .h)
- (void)fonctionAlaCon; // Sert à la déclarer. Pour éviter le la mettre tout au début.
// A mettre dans le main (fichier .m) n'importe où.
-(void)fonctionAlaCon {
lblMessage.text = @"Coucou monde";
}
// Pour l'appeler
[self fonctionAlaCon];
//Exemple2:
// A mettre dans le header (fichier .h)
- (int)unChiffre; // int détermine le format retourné
// A mettre dans le main (fichier .m) n'importe où.
-(int)unChiffre {
...
return 1; // donne à la fonction la valeure de 1
}
// Pour l'appeler
if ( [self unChiffre] == 1 )
//Exemple3:
// A mettre dans le header (fichier .h)
- (int)jeDoubleTout:(int)x; // Ajout du paramêtre x
// A mettre dans le main (fichier .m) n'importe où.
-(int)jeDoubleTout:(int)x {
...
return x*2; // prend le paramètre et transmet la valeure de retour
}
// Pour l'appeler
if ( [self jeDoubleTout:(2)] == 4 )
//Exemple4:
// A mettre dans le header (fichier .h)
- (int)jeDoubleTout:(int)x parCeci:(int)y; // Ajout du paramêtre x
// A mettre dans le main (fichier .m) n'importe où.
-(int)jeDoubleTout:(int)x parCeci:(int)y {
...
return x*y; // prend le paramètre et transmet la valeure de retour
}
// Pour l'appeler
if ( [self jeDoubleTout:(2) parCeci:(4)] == 8 )
Variables:
BOOL estRouge; // Booléan. valeures: YES et NO
int unNombre = 5; // Déclaration et définition d'une Integer
NSString *maVariable; // Déclaration d'un pointeur sur String (Immuable)
* Sur une variable, comme la variable age :
"age" signifie : "Je veux la valeur de la variable age".
"&age"
signifie : "Je veux l'adresse où se trouve la variable age".
* Sur un pointeur, comme pointeurSurAge :
"pointeurSurAge" signifie : "Je veux la valeur de pointeurSurAge"
(cette valeur étant une adresse).
"*pointeurSurAge" signifie : "Je veux la valeur de la variable qui se
trouve à l'adresse contenue dans pointeurSurAge"
IF:
if ( A == 30 ) // == veut dire =
if ( A != 30 ) // == veut dire Différent
if ( A >= 50 && A <= 60 ) // && veut dire AND
if ( A < 0 || A > 99 ) // || veut dire OR
Gestion des Strings (Chaine de caractères):
// un objet de classe NSString est le seul objet dont on a pas à gérer la mémoire.
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Prèt pour la gestion des strings
NSString *maVariable; // Déclaration d'une String (Immuable)
NSString *maVariable = @"Hello World!"; // Déclaration d'une String avec valeure
NSLog("Ceci est un String en C"); // Affiche du texte dans la console
NSLog(@"Ceci est un string en Objective-C");
maVariable = [NSString stringWithFormat:@"\nMon nombre : %d\n",unNombre]; // Opération sur une String
NSLog(maVariable); // On affiche la NSString dans la console
NSArray *listeDesCourses = [NSArray arrayWithObjects:@"Dentifrice", @"Pain", @"Stylos", nil]; // Création d'un tableau de Strings IMMUABLE
NSArray *tachesAFaire = [NSArray arrayWithObjects:listeDesCourses, @"Laver la voiture", nil]; // Encapsulation d'un tableau de Strings IMMUABLE
NSArray *unTableau = [NSArray arrayWithObjects:objet1, [NSNull null], objet3, nil]; // NSnull est utilisé car on ne peut pas avoir de trous dans un trableau
NSMutableArray *tableau = [NSMutableArray array]; // Création d'un tableau de Strings dynamique
[tableau addObject:@"Do"]; //Ajout d'un élément au tableau
[tableau insertObject:@"Ré" atIndex:0]; // = On a : @"Ré", @"Do" -> Insertion d'un élément
[tableau replaceObjectAtIndex:1 withObject:@"Mi"]; // = On a : @"Ré", @"Mi"
[tableau addObject:@"Fa"]; // = On a : @"Ré", @"Mi", @"Fa"
[tableau removeObjectAtIndex:0]; // = On a : @"Mi", @"Fa"
[tableau removeAllObjects]; // On vide tout le tableau
int nombreDObjets = [unTableau count]; // Crée une variable avec le nombre d'éléments dans un tableau
// Exemple de traitement d'un tableau
int i;
for (i = 0 ; i < [tableau count] ; i++) {
id unObjet = [tableau objectAtIndex:i]; // La méthode objectAtIndex: renvoie l'objet qui se trouve à l'index donné en paramètre.
[unObjet faireQuelqueChose];
}
// Pour obtenir l'index d'un objet
int positionHierarchie = [listeDesEmployes indexOfObject:jeanMarc]; //
La méthode indexOfObject fait exactement l'inverse de -
objectAtIndex:. Au lieu de retourner un objet d'index donné,
elle retourne l'index d'un objet donné. Pour cela, la
méthode compare l'objet passé en paramètre avec
les objets contenus dans le NSArray.
// Pour vérifier qu'un objet est dans un NSArray
if ([listeDesEmployes indexOfObject:gerard] != NSNotFound) {
// L'objet existe
}
id unObjet = [[tableau objectAtIndex:3] retain]; // Crée un pointeur vers l'objet du tableau mais le garde en mémoire en cas de libération du tableau
[tableau release]; // Libère le tableau
/* Et quand on a fini */
[unObjet release]; // Libère l'objet
int nb_caracteres = [chaine length]; // Pour connaitre la longueure d'une chaine
char caractere =
chaineC[3];
// Le caractère dans une chaine
char caractere = [chaineObjC characterAtIndex: 3]; // Le caractère dans une chaine
NSString *lesDeuxChaines = [maChaine1 stringByAppendingString:maChaine2]; // Composition de deux Strings
id chaine = [NSString stringWithFormat:@"Bonjour, mon nom est %@ et j'ai %d ans !", nom, age]; // Traitement d'une string avec autre chaine et nombre
if ( [chaine1 isEqualToString:chaine2] ) { // Condition sur une Chaine
}
[pool release]; //fin de la gestion des strings
Lien URL:
NSString *stringURL = @"http://salamin.eu/appiphone/index_iphone.html";
NSURL *url = [NSURL URLWithString:stringURL];
[[UIApplication
sharedApplication] openURL:url];
Tableau d'images:
// Générer les images, à mettre au début
UIImageView *tableauImages[4];
for (i=0; i<4; i++) {
tableauImages[i] = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image.png"]] autorelease];
tableauImages[i].frame = CGRectMake(1000, 0, 40, 40);
[self.view addSubview:tableauImages[i]];
}
// Déplacer une image
tableauImages[i].frame = CGRectMake(50, 50, 40, 40);
Objets:
// Tous les objets en Objective-C sont des pointeurs.
// On ne peut pas modifier des variables encapsulées dans un objet. Il faut créer une méthode.
id unObjet; // DECLARATION D'UN OBJET
id unObjet = nil; // Déclaration d'un objet (pointeur) de valeure nulle
[unObjet uneMethode] // Appeler la méthode d'un objet
[unObjet uneMethode:parametre] // Appeler la méthode d'un objet avec un paramètre
[uneCouleur couleurAvec:234 :192 :0]; // Appeler la méthode d'un objet avec des paramètre
[uneCouleur couleurAvecRouge:234 vert:192 bleu:0]; // Appeler la méthode d'un objet avec des paramètre
id uneForme = [Carre alloc]; // Initialise le pointeur "uneForme" de type "Carre" en exécutant la méthode "alloc" de l'objet "Carre"
[uneForme init]; // Retourne un id
id uneForme = [[Carre alloc] init]; // Englobe les deux méthodes ci-dessus. L'objet uneForme est pret à être utilisé.
id uneForme = [[Carre alloc] initAvecDimension:4]; // Crée l'objet avec une valeure
[uneForme rotation:45]; // Traitement de l'objet
[uneForme positionnerEnX:12 y:23];
[uneForme release]; // Libération (destruction) de l'objet
Carre *unCarre = [[Carre alloc] init]; // unCarre est de type Carre
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // pool est de type Autorelease
[pool release]; // Libération de l'objet pool
NSString *chaineAvecChaineObjC = [[NSString alloc] initWithString:@"Hello World!"]; // Un String étant un objet, chaineAvecChaineObjC est initialisé avec la valeure "Hello World!"
[chaineAvecChaineObjC release] // Libération de la chaine.
NSString *maVariable = @"Hello World!"; // Déclaration d'une String avec valeure SANS GESTION DE MEMOIRE!!!
Classes:
// Pour résumer, c'est un type d'objet
// A mettre dans le fichier .h -> Exemple de classe "voiture"
@interface Voiture : NSObject // Déclare la classe voiture qui hérite de NSObject
{
int kilometres;
int essence;
id moteur; // Objet générique inconnu
NSArray *passagers; // Tableau dynamique
}
- (id) init; //
Déclaration de la méthode d'instance (-) "init" ( ou
méthode d'objet). init DOIT toujours figurer dans une classe
+ (id) voitureAvecPassagers: (NSArray *) passagers; // Méthode de classe (+)
@end
// revenons dans le fichier .m -> Exemples d'utilisation de la classe ci-dessus:
Voiture *taxi = [Voiture voitureAvecPassagers:clients]; //On appelle bien la méthode de classe. Si on veut une Voiture sans passager, par exemple, on utilisera - init :
Voiture *tacot = [[Voiture alloc] init]; //Ici, on appelle la méthode de classe + alloc qui va allouer la mémoire pour chaque variable.
// implémentation des méthodes de l'objet, dans le fichier -m
@implementation Voiture
- (id) init {
// Du code...
[self faireLePlein]; //
self sert principalement à renvoyer l'objet
initialisé : en effet, - init doit toujours renvoyer l'objet
initialisé.
return self;
}
@end
// Autre exemple. Revenons dans le fichier header (.h)
@interface Personnage : NSObject
{
int vie;
int mana;
}
- (id) init;
- (int) vie;
- (int) mana;
- (void) setVie:(int) uneVie;
- (void) setMana:(int) unMana;
@end
// Goto .m pour l'implémentation
@implementation Personnage
- (id) init
{
[super init]; // On exécute la méthode - init de la classe mère
vie = 100;
mana = 100;
return self;
}
- (void) setMana: (int) aMana
{
if (aMana < 0)
mana = 0;
else
mana = aMana;
}
- (int) mana
{
return mana;
}
- (void) setArme:(Epee *)nouvelleArme
{
if (arme != nouvelleArme) {
[arme release];
[nouvelleArme retain];
arme = nouvelleArme;
}
}
- (void) dealloc
{
[epee release];
[bouclier release];
[super dealloc];
}
@end
Héritage:
// Exemples d'héritages de classes
#import <Foundation/Foundation.h>
@interface Personnage : NSObject // La classe personnage hérite de la classe NSObject
{
}
@end
#import <Foundation/Foundation.h>
#import "Personnage.h"
@interface Guerrier :
Personnage // La classe Guerrier hérite de la classe
Personnage (Qui lui-même hérite...)
{
}
@end
// Delegate est un
élément hérité qui demande une valeure
à son objet (le sens inverse de la normale, pour un retour de
méthode p.ex.)
delegate = notre_objet;
valeur = [delegate
tableau:self valeurPourColonne:3 ligne:4]; // La partie de la
méthode tableau:self sert à l'objet delegate pour savoir
qui appelle la méthode, et éventuellement lui demander
d'effectuer des tâches, etc.
Gestion de la mémoire:
retain // Augmente de 1 le compteur de référence d'un objet
release // Diminue de 1 le compteur de référence d'un objet
autorelease // Diminue de 1 le compteur de référence d'un objet à un certain moment dans le futur
alloc // Allocation de la mémoire pour un objet et le retourne avec un compteur de référence de 1
copy // Fait une copie d'un objet et le retourne avec un compteur de référence de 1
release // Libération pour cet objet. fais baisser le compteur "retain count" de 1
dealloc // Libération totale
[super dealloc]; //
Exécution de la méthode dealloc de la classe mère.
Le faire toujours en dernier.
MyObject *object = [[MyObject alloc] init]; // allocation mémoire puis initialisation
NSString *chaine_1 = [[NSString alloc] initWithString:@"Vous êtes le propriétaire"];
[chaine_1 release]
NSString *chaine_2 = [NSString stringWithString:@"Vous n'êtes pas le propriétaire"];
MyObject *object = [[MyObject alloc] init]; // retain count à 1
[object retain]; // retain count à 2
[object release]; // retain count à 1
[object release]; // retain count à 0 -> l'objet est détruit
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Objet qui gère les release automatiquement
[stringAConserver retain]; //Ce string-là restera après le "Pool release"
[pool release]; //fin de la gestion des releases
Accesseurs:
// dans .h
@property (retain) NSString *myString;
// dans .m
@synthesize myString
// dans une méthode
self.myString = aParameterStringForExample; // ici, le retain sera fait automatiquement !
Récupérer des fuites:
// Créez la méthode suivante:
- (void)createLeaks {
NSLog(@"createLeaks");
for(int i = 0 ; i < 100 ; i++)
{
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:30];
}
}
// Et l'appeler (après les releases p.ex.):
[self createLeaks];
// Puis aller dans run / start with performance tools / leaks
// une fenêtre s'ouvre... attendre durant l'exécution que le graph se remplit et une liste apparait
// Cliquez sur la ligne leaks, les fuites apparaissent
// Cliquez sur le petit rectangle épais sur la droite. En bas de l'écran vers le millieu
// Sur la droite apparaissent les causes des fuites. Un double-clic vous amène sur le code
Exemple de code:
// Fichier Arme.h
#import <Foundation/Foundation.h>
@interface Arme : NSObject
{
int degats;
}
- (id) initAvecDegats:(int) desDegats;
/* Accesseurs pour la variable degats */
- (int) degats;
- (void) setDegats:(int) nouveauxDegats;
- (NSString *) description;
@end
// Fichier Arme.m
#import "Arme.h"
@implementation Arme
- (id) initAvecDegats:(int) desDegats
{
if ( (self = [super init]) ) {
degats = desDegats;
}
return self;
}
- (int) degats
{
return degats;
}
- (void) setDegats:(int) nouveauxDegats
{
/* On s'arrête à 100 sinon on inflige plus de
dégâts que la vie de l'adversaire */
if (degats < 100)
degats = nouveauxDegats;
}
- (NSString *) description
{
/* On crée une NSString qui contient la description de l'épée */
return [NSString stringWithFormat:@"Degats : %d\n", degats];
}
@end
// Fichier Personnage.h
#import <Foundation/Foundation.h>
/* Obligatoire si on veut se servir de l'Arme */
#import "Arme.h"
@interface Personnage : NSObject
{
Arme * epee;
NSString * nom;
int vie;
}
- (id) initAvecNom:(NSString *) unNom;
- (void) dealloc;
/* Méthodes de jeu */
- (void) jouerContre:(Personnage *)adversaire;
- (void) recevoirDegats:(int)degats;
- (void) attaquer:(Personnage *)cible;
- (void) ameliorerEpee;
/* Accesseur pour vie */
- (int) vie;
- (NSString *) description;
@end
// Fichier Personnage.m
#import "Personnage.h"
@implementation Personnage
- (id) initAvecNom:(NSString *) unNom
{
if ( (self = [super init]) ) {
/* Création des différents objets */
epee = [[Arme alloc] initAvecDegats:10];
nom = [[NSString alloc] initWithString:unNom];
vie = 100;
}
return self;
}
- (void) dealloc
{
[epee release];
[nom release];
[super dealloc];
}
- (void) jouerContre:(Personnage *)adversaire
{
int reponse = 0;
/* Présentation du Personnage */
NSLog(@"\n%@", self);
/* On récupère une action de l'utilisateur */
do {
NSLog(@"\nFaites votre choix :\n1.Attaquer\n2.Améliorer votre
arme\nVotre choix : ");
scanf("%d", &reponse);
} while (reponse != 1 && reponse != 2);
if (reponse == 1)
[self attaquer:adversaire];
else if (reponse == 2)
[self ameliorerEpee];
}
- (void) recevoirDegats:(int)degats
{
vie -= degats;
/* On vérifie qu'on n'est pas négatif */
if (vie < 0)
vie = 0;
}
- (void) attaquer:(Personnage *)cible
{
int degatsAFaire = [epee degats];
[cible recevoirDegats:degatsAFaire];
}
- (void) ameliorerEpee
{
[epee setDegats:[epee degats] + 5]; // On augmente les dégâts de 5
}
- (int) vie
{
return vie;
}
- (NSString *) description
{
return [NSString stringWithFormat:@"Nom : %@\nVie : %d\n%@\n", nom, vie, epee];
}
@end
// Fichier main.m
#import <Foundation/Foundation.h>
#import "Personnage.h"
int main (void)
{
/* Variables :
* Une NSAutoreleasePool : indipensable.
* Deux Personnages pour jouer.
* Deux chaînes de caractères pour les noms.
* Deux NSString pour les noms en version NSString.
*/
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Personnage * joueur1, *joueur2;
char nom1[25] = "";
char nom2[25] = "";
NSString * nomJoueur1, * nomJoueur2;
/* On demande les noms
* /!\ Attention aux dépassements de mémoire. Un vrai programme ne
* serait pas codé comme ça. Il vaut mieux utiliser une fonction
* d'entrée sécurisée (voir tutoriel de M@teo21) /!\
*/
NSLog(@"\nEntrez votre nom, joueur 1 : ");
scanf("%s", nom1);
NSLog(@"\nEntrez votre nom, joueur 2 : ");
scanf("%s", nom2);
/* On les convertit en chaînes utilisables par notre classe Personnage */
nomJoueur1 = [NSString stringWithUTF8String:nom1];
nomJoueur2 = [NSString stringWithUTF8String:nom2];
/* On initialise nos Personnages */
joueur1 = [[Personnage alloc] initAvecNom:nomJoueur1];
joueur2 = [[Personnage alloc] initAvecNom:nomJoueur2];
/* On joue tant que les deux joueurs sont en vie */
while ( [joueur1 vie] > 0 && [joueur2 vie] > 0) {
[joueur1 jouerContre:joueur2];
/* Cette condition évite que le joueur 2 joue s'il est mort */
if ( [joueur2 vie] > 0)
[joueur2 jouerContre:joueur1];
}
/* On détermine le vainqueur : c'est celui auquel il reste de la vie */
Personnage * vainqueur = ([joueur1 vie] > 0) ? joueur1 : joueur2;
NSLog(@"\nVainqueur !!!\n%@", vainqueur);
/* On se débarrasse de nos objets */
[joueur1 release];
[joueur2 release];
/* On vide la NSAutoreleasePool : obligatoire */
[pool drain];
return 0;
}