50 votes

Dois-je faire référence à self.property dans la méthode init avec ARC ?

Une question rapide.

si j'ai une propriété et un ivar déclarés avec le même nom :

dans le fichier .h :

(Reminder*)reminder;
@property(nonatomic,strong)(Reminder*)reminder;

dans le fichier .m, dois-je utiliser l'ivar ou la propriété dans la méthode init si j'utilise l'ARC ?

- (id)initWithReminder:(Reminder*)reminder_ {
    self = [super init];
    if (self) {
        reminder = reminder_;
    }
    return self;
}

Ou dois-je utiliser la propriété pour bénéficier du comptage automatique des références comme ceci :

- (id)initWithReminder:(Reminder*)reminder_ {
    self = [super init];
    if (self) {
        self.reminder = reminder_;
    }
    return self;
}

Je ne sais pas à quel moment de l'initialisation de l'objet les propriétés deviennent accessibles avec la notation point.

67voto

justin Points 72871

Utiliser l'accès direct dans les états partiellement construits, indépendamment de l'ARC :

- (id)initWithReminder:(Reminder*)reminder_ {
    self = [super init];
    if (self) {
        reminder = reminder_;
        // OR
        reminder = [reminder_ retain];
    }
    return self;
}

Cela s'explique par le fait que self.whatever déclenchera d'autres effets secondaires, tels que des notifications de Key-Value Observing (KVO), ou peut-être que votre classe implémente (explicitement) ou qu'une sous-classe surcharge le paramètre setWhatever: -- et cela pourrait exposer votre instance partiellement initialisée à d'autres API (y compris la sienne), qui supposent à juste titre qu'elles ont affaire à un objet entièrement construit.

Usted pourrait vérifier manuellement qu'une classe est capable de fonctionner dans un état partiellement initialisé, mais cela demande beaucoup de maintenance et est (franchement) peu pratique ou impossible lorsque d'autres personnes veulent sous-classer votre classe. Cela demande beaucoup de temps et de maintenance, et il n'y a pas d'avantage substantiel à le faire, surtout si vous essayez d'utiliser cette approche comme une convention.

Ainsi, la manière uniforme qui garantit la correction est d'utiliser l'accès direct dans les états partiellement construits, et d'éviter d'utiliser les accesseurs.

Note : J'utilise l'expression "partiellement construit" parce que l'initialisation n'est que la moitié de l'image ; -dealloc a des réserves similaires.

Vous trouverez plus de détails sur la raison pour laquelle vous devriez utiliser l'accès direct dans les états partiellement construits (ARC || MRC) ici : Initialisation d'une propriété, notation par points

5voto

Konstantin Koval Points 804

Non, vous ne devriez pas !

Vous pouvez trouver la description du pourquoi aquí
Aussi la pomme recommande de ne pas le faire. Lire ici

0voto

user1864957 Points 41

Je ne sais pas à quel moment de l'initialisation de l'objet les propriétés deviennent accessibles avec la notation point.

Puisque la notation par points est toujours une méthode Objective-C (et une méthode C en fait sous la méthode ObjC), la notation par points, ou l'appel de la méthode, est parfaitement sûre, POURVU que la méthode soit préparée à traiter le(s) type(s) sous-jacent(s) en mémoire dans n'importe quel état où ils se trouvent. La règle normale consistant à éviter l'utilisation d'un segment de mémoire non initialisé (éventuellement) dans un garage s'applique toujours. Ce qui est la motivation la plus forte pour l'utilisation de l'ivar dans l'init.

Mais si votre méthode (getter|setter) est capable d'utiliser correctement le segment de mémoire - indépendamment du fait qu'il soit d'abord écrit avant d'être lu - alors vous pouvez utiliser votre getter dans la méthode init. Un getter paresseux tire parti de l'hypothèse selon laquelle un pointeur qu'il va initialiser commence par 'nil' pour décider d'effectuer l'initialisation. Si vous ne pouvez pas supposer le contenu initial de votre mémoire, l'initialisation de l'ivar peut être la solution la plus sûre.

Pourquoi avoir la règle de ne jamais utiliser de setters ou de getters dans l'init si la méthode est capable de fonctionner correctement dans ce scénario ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X