Bien coder                       Sur iOSCocoaHeads Rennes                     Julien QUERE 8 septembre 2011               ...
Pour qui ? Pourquoi ?Pour l’utilisateur              Pour le futur✓    Performance                                ✓ Compré...
Coding guidelines« L’important, ce n’est pas les règles, c’est le               fait d’en avoir »                         ...
Formatage- (NSURL*) url {! NSString * url = [NSString stringWithString:kWDGdirectionsBaseURL];! NSDictionary *      parame...
Formatage-   (NSURL*) url {!    NSString * url = [NSString stringWithString:kWDGdirectionsBaseURL];!    NSDictionary * par...
Formatage➡   Un code propre = code compréhensible➡   Surveiller: l’indentation, le placement des délimiteurs, ...
NommageIl faut pouvoir facilement différencier:➡   Une variable statique➡   Une variable d’instance➡   Un attribut➡   Une ...
La règle de 3➡   Je développe une routine une fois➡   Seconde fois: je me pose des questions➡   Troisième fois: je factorise
- (void) displayTopTweets:(NSArray*)tweets {! if([tweets count] == 4) {! !    [tweetButton1_.titleLabel setNumberOfLines:2...
- (void) displayTopTweets:(NSArray*)tweets {    !       NSArray * buttons = [NSArray arrayWithObjects:tweetButton1_, tweet...
Utiliser des constantes➡ Pas de valeur numérique / textuelle «en dur»➡ Utiliser des constantes➡ Utiliser un fichier de loca...
Définir ses propres guidelines➡   Prendre le temps et du recul➡   Intégrer toute l’équipe dans le processus➡   Ne pas hésit...
Gestion intelligente des       ressources« Quand on est pauvre, on na que la      ressource dêtre sage. »                 ...
Quelles ressources ?Batterie   Echanges   Mémoire            réseau
BatteriePour gagner en autonomie, iOS désactive le materiel dés quepossible: ➡   CPU ➡   Radio (Wi-Fi, Bluetooth, GPS, EDG...
Batterie: L’exemple Core               Location➡   Solution simple:    - (BOOL)application:(UIApplication *)application di...
Batterie: L’exemple Core              Location➡ Solution économique:➡ Ne lancer Core Location que quand c’est nécessaire➡ ...
Batterie - Mais aussi➡   Eviter tout calcul inutile➡   Ne jamais utiliser [application   setIdleTimerDisabled:YES]   sans ...
Réseau➡   Choisissez bien votre format !             19 Ko                                                       18,05 Ko➡...
Réseau➡   Ne prendre ce qui est nécessaire➡   Pourquoi télécharger 100 tweets sur les CocoaHeads alors    qu’on en afficher...
Réseau➡   Malheureusement, on n’a pas toujours la main sur la    plateforme Web➡ Il faut s’en accommoder➡ Commencer la réfl...
La mémoire« La mémoire, cest comme une valise. On  met toujours dedans des choses qui ne             servent à rien.»     ...
La mémoire➡ Objectif: réduire son emprunte mémoire:➡ Consommer le moins de mémoire, le moins longtemps    possible.
La mémoire                                                 Plus les appareils montent en                                  ...
La mémoire➡ Principales sources de « gaspillage »:➡ Les fuites➡ La mémoire allouée inutilement➡ La mémoire libérée trop tard
La mémoireRappel: 1 retain / alloc / copy = 1 release
Gare à l’autoRelease !➡   Tout objet en autorelease est placé dans le bassin le plus    «proche»➡   Quand le bassin est vi...
Gare à l’autoRelease !             NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];             TBXML * tbxml ...
Gare à l’autoRelease !             TBXML * tbxml = [[TBXML alloc] initWithXMLData:xmlData];             TBXMLElement *root...
Le Dealloc➡   Un dealloc vide ou incomplet: c’est la garantie de fuites    mémoire.➡   Astuce 1: A la création d’une varia...
Be lazy- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {    self = [super initWithNibName...
Be lazy- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {    self = [super initWithNibName...
Memory warning➡   Le memory warning signifie que le système va être à court de    mémoire.➡   Soyez courtois, et libérez to...
Memory warning    Trois options pour être tenu au courant:➡   Dans un ViewController: -            (void) didReceiveMemory...
Crash et ralentissement  « Développement : Alliance dune scienceinexacte et dune activité humaine faillible.»             ...
Crash et ralentissement
Core Data➡   Un NSManagedObjectContext ne peux être partagé entre    plusieurs threads➡   Un NSManagedObject n’est valide ...
Core Data                                                      1              2  ObjectID                                 ...
Mais aussi ...➡   Être très rigoureux sur la gestion des retain / release➡   User et abuser du respondsToSelector:➡   Touj...
Analyser« Louvrier qui veut bien faire son travail doit commencer par aiguiser ses instruments. »                         ...
AnalyserCe que je voulais    Ce que je pense   Ce que j’ai     faire              avoir fait        fait
Analyser➡   Analyser, c’est comprendre ce qui a été réellement fait➡   Instruments est l’outil parfait pour ça:        Con...
Conclusions« Je sens que, ce soir, je vais conclure »                                         Jean-Claude Dusse
Conclusions➡   Bien coder, c’est du temps, de la crédibilité et de l’argent de    gagné.➡   Définir des règles intelligemme...
julien@cocoaheads.fr  CocoaHeads #3                     thomas.dupont@cocoaheads.frBien débuter sur iOS   Mail   : jeremy....
Prochain SlideShare
Chargement dans…5
×

Cocoaheads Rennes #3 : Bien coder sur iOS

5 281 vues

Publié le

Slides de la présentation "Bien coder sur iOS" de la session des CocoaHeads Rennais du 08 septembre 2011. Présentation assurée par Julien Quéré, co-organisateur.

Publié dans : Technologie
0 commentaire
0 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Aucun téléchargement
Vues
Nombre de vues
5 281
Sur SlideShare
0
Issues des intégrations
0
Intégrations
3 539
Actions
Partages
0
Téléchargements
22
Commentaires
0
J’aime
0
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Cocoaheads Rennes #3 : Bien coder sur iOS

  1. 1. Bien coder Sur iOSCocoaHeads Rennes Julien QUERE 8 septembre 2011 julien@cocoaheads.fr
  2. 2. Pour qui ? Pourquoi ?Pour l’utilisateur Pour le futur✓ Performance ✓ Compréhensibilité✓ Stabilité ✓ Flexibilité‣ Moins de bugs ✓ Réutilisabilité‣ Moins de retours ‣ Maintenance et évolutions plus aisés‣ Une meilleure expérience utilisateur/client ‣ Projets plus rapides➡ Gain de temps ➡Gain de temps➡ Gain en crédibilité ➡Gain en réactivité
  3. 3. Coding guidelines« L’important, ce n’est pas les règles, c’est le fait d’en avoir » J.
  4. 4. Formatage- (NSURL*) url {! NSString * url = [NSString stringWithString:kWDGdirectionsBaseURL];! NSDictionary * parameters = [self parameters];!! if(parameters)! {! BOOL isFirstKey = YES;! ! ! ! NSString * separator = @"?";! !! ! ! for (NSString * key in [parameters allKeys]) {! ! ! url = [url stringByAppendingFormat:@"%@%@=%@", separator, key, [parametersvalueForKey:key]];! ! !! ! ! if(isFirstKey)! ! {! ! ! isFirstKey = NO;! ! ! ! separator = @"&";! ! ! }! ! }! ! }! ! ! ! ! url = [url stringByAddingPercentEscapesUsingEncoding:! ! NSUTF8StringEncoding];! return [NSURL URLWithString:url];}
  5. 5. Formatage- (NSURL*) url {! NSString * url = [NSString stringWithString:kWDGdirectionsBaseURL];! NSDictionary * parameters = [self parameters];!! if(parameters) {! ! BOOL isFirstKey = YES;! ! NSString * separator = @"?";! !! ! for (NSString * key in [parameters allKeys]) {! ! ! url = [url stringByAppendingFormat:@"%@%@=%@", separator, key, [parameters valueForKey:key]];! ! !! ! ! if(isFirstKey) {! ! ! ! isFirstKey = NO;! ! ! ! separator = @"&";! ! ! }! ! }! }! url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];! return [NSURL URLWithString:url];}
  6. 6. Formatage➡ Un code propre = code compréhensible➡ Surveiller: l’indentation, le placement des délimiteurs, ...
  7. 7. NommageIl faut pouvoir facilement différencier:➡ Une variable statique➡ Une variable d’instance➡ Un attribut➡ Une variable de classe➡ Une variable locale
  8. 8. La règle de 3➡ Je développe une routine une fois➡ Seconde fois: je me pose des questions➡ Troisième fois: je factorise
  9. 9. - (void) displayTopTweets:(NSArray*)tweets {! if([tweets count] == 4) {! ! [tweetButton1_.titleLabel setNumberOfLines:2];! ! [tweetButton1_ setTitle:[tweets objectAtIndex:0]! ! ! ! ! forState:UIControlStateNormal];! ! [tweetButton1_ setTitle:[[tweets objectAtIndex:0] uppercaseString]! ! ! ! ! forState:UIControlStateHighlighted];! ! [tweetButton1_ setHidden:NO];!! ! [tweetButton2_.titleLabel setNumberOfLines:2];! ! [tweetButton2_ setTitle:[tweets objectAtIndex:1]! ! ! ! ! forState:UIControlStateNormal];! ! [tweetButton2_ setTitle:[[tweets objectAtIndex:1] uppercaseString]! ! ! ! ! forState:UIControlStateHighlighted];! ! [tweetButton2_ setHidden:NO];! !! ! [tweetButton3_.titleLabel setNumberOfLines:2];! ! [tweetButton3_ setTitle:[tweets objectAtIndex:2]! ! ! ! ! forState:UIControlStateNormal];! ! [tweetButton3_ setTitle:[[tweets objectAtIndex:2] uppercaseString]! ! ! ! ! forState:UIControlStateHighlighted];! ! [tweetButton3_ setHidden:NO];! !! ! [tweetButton4_.titleLabel setNumberOfLines:2];! ! [tweetButton4_ setTitle:[tweets objectAtIndex:3]! ! ! ! ! forState:UIControlStateNormal];! ! [tweetButton4_ setTitle:[[tweets objectAtIndex:3] uppercaseString]! ! ! ! ! forState:UIControlStateHighlighted];! ! [tweetButton4_ setHidden:NO];!!! !}}
  10. 10. - (void) displayTopTweets:(NSArray*)tweets { ! NSArray * buttons = [NSArray arrayWithObjects:tweetButton1_, tweetButton2_, ! ! ! ! ! ! tweetButton3_, tweetButton4_, nil]; ! if([buttons count] == [tweets count]) {! ! ! for (NSUInteger i = 0; i < [buttons count]; i++) { ! ! ! UIButton * button = [buttons objectAtIndex:i]; ! ! ! NSString * tweet = [tweets objectAtIndex:i]; ! ! ! ! ! ! [button.titleLabel setNumberOfLines:2]; ! ! ! [button setTitle:tweet ! ! ! ! ! forState:UIControlStateNormal]; ! ! ! [button setTitle:[tweet uppercaseString] ! ! ! ! ! forState:UIControlStateHighlighted]; ! ! ! [button setHidden:NO]; ! ! }! ! } }! !! !
  11. 11. Utiliser des constantes➡ Pas de valeur numérique / textuelle «en dur»➡ Utiliser des constantes➡ Utiliser un fichier de locales
  12. 12. Définir ses propres guidelines➡ Prendre le temps et du recul➡ Intégrer toute l’équipe dans le processus➡ Ne pas hésiter à se baser sur des guidelines existantes Google Objective-C Style Guide http://google-styleguide.googlecode.com/svn/trunk/objcguide.xml
  13. 13. Gestion intelligente des ressources« Quand on est pauvre, on na que la ressource dêtre sage. » Jean-Pierre Florian
  14. 14. Quelles ressources ?Batterie Echanges Mémoire réseau
  15. 15. BatteriePour gagner en autonomie, iOS désactive le materiel dés quepossible: ➡ CPU ➡ Radio (Wi-Fi, Bluetooth, GPS, EDGE/3G) ➡ Accéléromètre / gyroscope C’est en réduisant l’usage ➡ Boussole de ces matériels que l’on ➡ Disque (stockage flash) augmente l’autonomie ➡ Ecran
  16. 16. Batterie: L’exemple Core Location➡ Solution simple: - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *) launchOptions { ! manager_ = [[CLLocationManager alloc] init]; ! manager_.desiredAccuracy = kCLLocationAccuracyBestForNavigation; ! manager_.delegate = self; ! [manager_ startUpdatingLocation];➡ Core Location va mettre à jour la position en continu ...➡ ... jusquà ce que la batterie soit vide
  17. 17. Batterie: L’exemple Core Location➡ Solution économique:➡ Ne lancer Core Location que quand c’est nécessaire➡ Régler la précision avec intelligence➡ Ne pas laisser tourner Core Location inutilement
  18. 18. Batterie - Mais aussi➡ Eviter tout calcul inutile➡ Ne jamais utiliser [application setIdleTimerDisabled:YES] sans raison➡ Eviter les accès trop fréquents au disque➡ Ne dessiner que ce qui est nécessaire➡ Utiliser laccéléromètre / gyroscope avec autant de parcimonie que Core Location➡ Limiter les accès réseau
  19. 19. Réseau➡ Choisissez bien votre format ! 19 Ko 18,05 Ko➡ Exemple avec recherche twitter 14 Ko Le JSON est 52% moins 10 Ko 9,47 Ko lourd que le XML 5 KoDonnées calculées sur la moyenne de 100 0 Ko appels à l’API Twitter en JSON vs XML Taille de la réponse http://search.twitter.com/search.json? XML JSON q=cocoaheads&result_type=mixed&count=100
  20. 20. Réseau➡ Ne prendre ce qui est nécessaire➡ Pourquoi télécharger 100 tweets sur les CocoaHeads alors qu’on en affichera que 15 ?➡ Astuce: utiliser la pagination➡ Mais ne pas en abuser: éviter de trop nombreuses petites requêtes
  21. 21. Réseau➡ Malheureusement, on n’a pas toujours la main sur la plateforme Web➡ Il faut s’en accommoder➡ Commencer la réflexion en partant du mobile dès que possible
  22. 22. La mémoire« La mémoire, cest comme une valise. On met toujours dedans des choses qui ne servent à rien.» Walter Prévost
  23. 23. La mémoire➡ Objectif: réduire son emprunte mémoire:➡ Consommer le moins de mémoire, le moins longtemps possible.
  24. 24. La mémoire Plus les appareils montent en gamme plus il y a de mémoire.128 Mo Cependant, iOS est de plus en plus 58 Mo96 Mo gourmand avec le temps 4 Mo64 Mo 10 Mo Disponible 12 Mo Téléphone Springboard32 Mo 32 Mo Démons Kernel 12 Mo Couche graphique 0 Mo Source: Apple TechTalks Paris 2009 Valeurs pour un iPhone 3G
  25. 25. La mémoire➡ Principales sources de « gaspillage »:➡ Les fuites➡ La mémoire allouée inutilement➡ La mémoire libérée trop tard
  26. 26. La mémoireRappel: 1 retain / alloc / copy = 1 release
  27. 27. Gare à l’autoRelease !➡ Tout objet en autorelease est placé dans le bassin le plus «proche»➡ Quand le bassin est vidé, il envoie un Release à chacun des objets qu’il gère L’autorelease très pratique, mais il faut redoubler de vigilance
  28. 28. Gare à l’autoRelease ! NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; TBXML * tbxml = [[TBXML alloc] initWithXMLData:xmlData]; TBXMLElement *root = tbxml.rootXMLElement; if (root) { TBXMLElement *item = [TBXML childElementNamed:@"item" parentElement:root]; while (item != nil) { // Parsing code item = [TBXML nextSiblingNamed:@"item" searchFromElement:item]; } } [tbxml release]; [pool release];50MB 49MB38MB 35MB25MB 20MB13MB 5MB 5MB 5MB 5MB0MB Parsing d’un fichier XML basé sur le Top 300 iTunes avec TBXML 1.4. Mesures effectuées avec instruments.
  29. 29. Gare à l’autoRelease ! TBXML * tbxml = [[TBXML alloc] initWithXMLData:xmlData]; TBXMLElement *root = tbxml.rootXMLElement; if (root) { TBXMLElement *item = [TBXML childElementNamed:@"item" parentElement:root]; while (item != nil) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // Parsing code [pool release]; item = [TBXML nextSiblingNamed:@"item" searchFromElement:item]; } } [tbxml release]; Une gestion fine de l’autorelease, c’est une gestion fine de la mémoire50MB 49MB38MB 35MB25MB 20MB13MB 12MB 12MB 5MB 7MB 5MB 5MB 5MB0MB Parsing d’un fichier XML basé sur le Top 300 iTunes avec TBXML 1.4. Mesures effectuées avec instruments.
  30. 30. Le Dealloc➡ Un dealloc vide ou incomplet: c’est la garantie de fuites mémoire.➡ Astuce 1: A la création d’une variable d’instance, on la met de suite dans le dealloc (si il y a lieu).➡ Astuce 2: Mettre les variable dans le même ordre dans l’interface que dans le dealloc.➡ Ne jamais oublier le [super dealloc];
  31. 31. Be lazy- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self != nil) { credits_ = [[NSString stringWithContentsOfFile:filePath] retain]; } return self;}- (IBAction) showCredits:(UIButton*) sender {! [self displayTextPopup:credits_];}- (void) dealloc {! [credits_ release];! [super dealloc];}
  32. 32. Be lazy- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self != nil) { } return self;}- (NSString*)credits {! if(!credits_) { credits_ = [[NSString stringWithContentsOfFile:filePath] retain];! }!! return credits_;}- (IBAction) showCredits:(UIButton*) sender {! [self displayTextPopup:[self credits]];! !}- (void) dealloc {! [credits_ release];! [super dealloc];}
  33. 33. Memory warning➡ Le memory warning signifie que le système va être à court de mémoire.➡ Soyez courtois, et libérez tout ce que vous pouvez.➡ Rappelez vous, le système a la License To Kill.
  34. 34. Memory warning Trois options pour être tenu au courant:➡ Dans un ViewController: - (void) didReceiveMemoryWarning;➡ Dans l’UIApplicationDelegte: - (void) applicationDidReceiveMemoryWarning:(UIApplication *)application;➡ Partout ailleurs: UIApplicationDidReceiveMemoryWarningNotification
  35. 35. Crash et ralentissement « Développement : Alliance dune scienceinexacte et dune activité humaine faillible.» Luc Fayard
  36. 36. Crash et ralentissement
  37. 37. Core Data➡ Un NSManagedObjectContext ne peux être partagé entre plusieurs threads➡ Un NSManagedObject n’est valide que dans son NSManagedObjectContext➡ Conséquence: il ne faut pas passer de NSManagedObject entre plusieurs threads !
  38. 38. Core Data 1 2 ObjectID ObjectID 3 3Thread 1 / MOC 1 Thread 2 / MOC 2 NSString * monObjectId = [monObjet objectID]; [monContext objectWithID:monObjectId];
  39. 39. Mais aussi ...➡ Être très rigoureux sur la gestion des retain / release➡ User et abuser du respondsToSelector:➡ Toujours penser aux cas aux limites➡ Instruments offre des outils pour tracer et comprendre tout ça ...
  40. 40. Analyser« Louvrier qui veut bien faire son travail doit commencer par aiguiser ses instruments. »  Confucius
  41. 41. AnalyserCe que je voulais Ce que je pense Ce que j’ai faire avoir fait fait
  42. 42. Analyser➡ Analyser, c’est comprendre ce qui a été réellement fait➡ Instruments est l’outil parfait pour ça: Consommation Fuites Consommation mémoire mémoire d’énergie Performances graphiques Zombies
  43. 43. Conclusions« Je sens que, ce soir, je vais conclure » Jean-Claude Dusse
  44. 44. Conclusions➡ Bien coder, c’est du temps, de la crédibilité et de l’argent de gagné.➡ Définir des règles intelligemment ... et s’y tenir !➡ Soyez courtois avec les ressources➡ Lisez, creusez et comprenez la documentation ...
  45. 45. julien@cocoaheads.fr CocoaHeads #3 thomas.dupont@cocoaheads.frBien débuter sur iOS Mail : jeremy.brault@niji.fr Web : www.niji.frBien coder sur iOS Mail : julien@cocoaheads.fr Web : www.cocoaheads.fr Twitter : @CocoaHeadsRNS

×