Il fait trop chaud pour… se répéter

Pour ceux qui continuent de coder pour iOS dans la torpeur estivale qui a saisi le pays, une petite astuce, permise par le SDK 4, qui pourrait vous économiser quelques gouttes de sueur.

On adore tous le mot-clé @synthesize qui nous évite déjà d’avoir à tartiner des accesseurs sans intérêt. Malheureusement, pour créer une propriété simple, jusqu’à présent il fallait encore définir séparément le stockage (variable d’instance ou ivar pour les intimes et les Scandinaves) et la propriété elle-même, avec le mot-clé @property :

@interface MaClasse: NSObject {
    NSString *truc;
}
@property(retain) NSString *truc;
@end

@implementation MaClasse
@synthesize truc;
@end

Or, dans la documentation des Declared Properties, on trouve la phrase suivante :

For the modern runtimes (see Runtime Versions and Platforms in Objective-C Runtime Programming Guide), instance variables are synthesized as needed.

Et si on suit la référence indiquée on arrive à :

iPhone applications and 64-bit programs on Mac OS X v10.5 and later use the modern version of the runtime.

Tout est donc OK, on devrait pouvoir profiter de cette fonctionnalité dans les projets iPhone !

Toujours à l’affut de l’économie de lignes de code, quand j’avais lu cette documentation je m’étais précipité sur le projet iPhone le plus proche, avais enlevé une définition d’ivar théoriquement inutile et tenté de compiler le code ainsi allégé :

@interface MaClasse: NSObject {
}
@property(retain) NSString *truc;
@end

@implementation MaClasse
@synthesize truc;
@end

Hélas, quelle déception ! Le compilateur ne semblait pas avoir lu le texte sus-cité et s’entêtait à exiger la définition redondante.
Comme d’habitude Google détenait la clé du mystère : si le code incriminé était rejeté, c’est parce que je compilais pour le simulateur ! Quel rapport me direz-vous ? Eh bien comme vous le savez sans doute, le simulateur iPhone est une application OS X 32 bits… qui ne bénéficie donc pas du fameux modern runtime. Effectivement, le code sans ivar se compilait sans problème dès que je choisissais “Device” comme cible.

Je n’étais bien entendu pas le premier à découvrir ce déplorable état de fait (difficile d’abandonner le simulateur pour économiser quelques lignes par classe !), et la conclusion généralement admise était qu’il perdurerait longtemps, Apple ayant choisi de ne pas rendre le modern runtime accessible aux applications OS X 32 bits, et compiler le simulateur en 64 bits étant exclu pour des raisons évidentes.

C’était sans compter… je ne sais quoi au juste, l’ingéniosité d’un développeur Apple ? Un caprice de Steve ? Toujours est-il que, sans tambour ni trompette (ce n’est même pas mentionné dans les release notes, et le bug radar n’est pas fermé !), le simulateur fourni avec le SDK 4, tout en restant une application 32 bits, utilise le modern runtime – et le compilateur associé est naturellement au courant.

Tout ça (oui, ça fait beaucoup de texte pour parler d’économies de lignes de code !) pour dire que dès aujourd’hui, si vous développez pour iOS (quelle que soit la deployment target, du moment que vous compilez avec le SDK 4), vous pouvez tirer parti de l’instance variable synthesis et omettre ces définitions décidément pas DRY.

Pour finir, à ceux qui n’auront de cesse que la dernière source de duplication stérile de code soit éliminée, et continuent de déplorer qu’il faille encore enfoncer le clou de chaque @property par un @synthesize, sachez qu’il existe un espoir : le compilateur LLVM serait capable d’inférer ces déclarations @synthesize, en l’absence bien sûr d’accesseurs explicites (plus de détails ici). Il semble qu’une petite limitation ternisse encore ce tableau presque idyllique, mais le nirvanā de la propriété en une ligne est plus que jamais à portée de main !

2 thoughts on “Il fait trop chaud pour… se répéter

  1. Ca fait une bonne raison de plus de passer en 64 bits et de ne pas supporter les OS pré-Léopard !

  2. “derniere source de duplication” – oui enfin, il reste encore les messages release à passer à chaque @property dans la méthode dealloc, et ça on est encore loin d’éliminer en l’absence de GC sous iOS.

Leave a Reply

Your email address will not be published. Required fields are marked *