Question

J'ai entendu maintenant de plusieurs sources (stackoverflow.com, cacao-dev, la documentation, les blogs, etc.) qu'il est « mauvais » à utiliser accesseurs et les paramètres (foo, setFoo :) dans vos méthodes d'initialisation et dealloc . Je comprends qu'il ya il y a une possibilité à distance de confondre d'autres objets qui observaient la propriété si vous le faites. (Un exemple simple est donnée )

Cependant, je dois dire que je ne suis pas d'accord avec cette pratique pour la raison suivante:

Le nouvel objectif-C runtime (celui sur l'iPhone et le moteur d'exécution 64 bits 10.5) permet de déclarer les propriétés sans en déclarant un Ivar correspondant. Par exemple, la classe suivante compilera très bien sur 10.5 ou pour l'iPhone (appareil, simulateur non):

@interface Foo : NSObject { }

  @property (retain) id someObject;

@end

@implementation Foo

  @synthesize someObject;

@end

Comprendre que ce qui précède est une classe Objective-C parfaitement valide, disons que je décide d'écrire un initialiseur, et à des fins de gestion de la mémoire, une méthode dealloc (puisque GC n'est pas disponible sur l'iPhone). Tout ce que j'ai jamais lu initializers et désallocation me conduit à écrire les deux méthodes suivantes:

- (id) init {
  if (self = [super init]) {
    //initialize the value of someObject to nil
    [self setSomeObject:nil];
  }
  return self;
}

- (void) dealloc {
  //setting someObject to nil will release the previous value
  [self setSomeObject:nil];
  [super dealloc];
}

Toutefois, d'après la documentation et l'opinion populaire, c'est « mauvais ». Mes questions sont ceci:

  1. Comment dois-je initialiser someObject sans utiliser l'accesseur? Vous pourriez dire que le compilateur (ou exécution ou autre) veillera à ce que someObject est déjà fixé à zéro, mais je crois que ce serait un comportement inapproprié de se fier à ce sujet. Avoir un fond décent dans C, j'ai vu un bon nombre de bugs en raison de ne pas correctement les variables d'initialisation, et cela semble peu différent.
  2. Comment puis-je libérer someObject si je ne suis pas censé utiliser l'accesseur dans la méthode dealloc?

Si la réponse à l'une de ces derniers est « vous ne pouvez pas », alors comment peut-il être mauvais d'utiliser accesseurs dans vos méthodes d'initialisation et dealloc?

Était-ce utile?

La solution

Je comprends que le comportement 10.5 actuel dans lequel les Ivars synthétisés ne sont pas directement accessibles est considéré par Apple pour être un bogue; vous devriez être en mesure d'accéder directement, mais ne peut pas.

Par conséquent, vous devriez être en mesure de le faire:

someObject = nil;

au lieu de

self.someObject = nil;

Dans l'intervalle, en utilisant l'accesseur est directement la seule façon de le faire sans fournir une Ivar explicite.

Mise à jour : Ce bug a été corrigé; vous pouvez maintenant faire someObject = nil bien.

Autres conseils

EDIT (13 février 2013): Comme indiqué dans mon commentaire ci-dessous, et surtout depuis l'ajout de l'ARC, j'ai changé d'avis à ce sujet. Avant ARC, j'ai vu beaucoup de bugs causant l'accident en raison de travaux de Ivar incorrectes dans init. OMI, travaillant en particulier avec les équipes juniors, les rares problèmes liés à l'utilisation des accesseurs dans init ont été compensés par les insectes communs d'accès Ivar. Depuis ARC a éliminé ces sortes d'insectes, les insectes rares, mais que l'utilisation possible-accesseur en init peut causer sont plus importants, et donc je suis passé à soutenir l'utilisation directe de Ivars dans init et dealloc, et seulement dans ces lieux ; accesseurs partout ailleurs qui est possible (vous pouvez évidemment pas utiliser accesseurs à l'intérieur de l'accesseur lui-même ....)


Réponse préarc

Je suis en désaccord avec ceux qui s'y opposent à accesseurs en -init. Dans presque tous les cas, il est un très bon endroit pour utiliser accesseurs, et il permet d'économiser beaucoup de bugs que j'ai vu dans les nouveaux codeurs de cacao qui ne invariablement à retenir lors de l'attribution à -init.

-dealloc est un appel plus difficile. J'ai une inclination naturelle à utiliser il accesseurs (de sorte qu'ils sont utilisés partout), mais il peut causer des maux de tête en raison de KVO (ou même NSNotifications si vous postez une notification de changement dans votre setter). Cela dit, alors que je ne l'utilise accesseurs dans -dealloc, je considère qu'il est très discutable et Apple est très contradictoire à ce sujet (nous savons qu'ils appellent setView: dans -dealloc par exemple de UIViewController).

Dans tous les cas, je dirais que la sous-utilisation des accesseurs a causé 100x les bugs de surutilisation. Je serais toujours errer vers les utiliser, sauf quand il y a une bonne raison de ne pas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top