J'ai appris quelque chose de nouveau tout en essayant de comprendre pourquoi mon readwrite bien déclaré en privé, la Catégorie n'était pas de la génération d'un setter. C'était à cause de ma Catégorie a été nommé:
// .m
@interface MyClass (private)
@property (readwrite, copy) NSArray* myProperty;
@end
Changer l':
// .m
@interface MyClass ()
@property (readwrite, copy) NSArray* myProperty;
@end
et mon setter est synthétisé. Je sais maintenant que l'Extension de Classe n'est pas juste un autre nom pour un anonyme de la Catégorie. Laissant une Catégorie sans nom qu'il provoque, pour se transformer en une bête différente: l'une qui donne maintenant au moment de la compilation de la méthode de la mise en œuvre de l'application et permet d'ajouter ivars. Je comprends maintenant le général philosophies qui sous-tendent chacune de ces Catégories sont généralement utilisés pour ajouter des méthodes à une classe quelconque au moment de l'exécution, et les Extensions de la Classe sont généralement utilisés pour appliquer privé implémentation de l'API et ajouter ivars. Je l'assume.
Mais il y a des bricoles qui me confondre. Tout d'abord, à un haut niveau: Pourquoi différencier de ce genre? Ces concepts semblent comme des idées similaires qui ne peut pas décider si elles sont identiques, ou différents concepts. Si elles sont les mêmes, je m'attends à voir les mêmes choses exactes possibles en utilisant une Catégorie sans nom, comme c'est avec un nom de la Catégorie (qui ne le sont pas). Si elles sont différentes, (qui ils sont), je m'attends à une plus grande syntaxique disparité entre les deux. Il semble étrange à dire, "Oh, en passant, pour mettre en œuvre une Extension de Classe, il suffit d'écrire une Catégorie, mais de laisser le nom. Il change par magie."
Deuxièmement, sur le sujet de la compilation de l'application: Si vous ne pouvez pas ajouter des propriétés à un nom de Catégorie, pourquoi ne le faire convaincre le compilateur que vous n'avez juste qu'? Pour être clair, je vais illustrer avec mon exemple. Je peux déclarer une propriété en lecture seule dans le fichier d'en-tête:
// .h
@interface MyClass : NSObject
@property (readonly, copy) NSString* myString;
@end
Maintenant, je veux sur la tête à la mise en œuvre de fichier et me donner privé readwrite l'accès à la propriété. Si je le fais correctement:
// .m
@interface MyClass ()
@property (readwrite, copy) NSString* myString;
@end
Je reçois un avertissement lorsque je n'ai pas synthétiser, et quand je le fais, je peux définir le bien et tout est peachy. Mais, malheureusement, si je venais à être légèrement erronées à propos de la différence entre la Catégorie et la Classe de l'Extension et j'ai essayer:
// .m
@interface MyClass (private)
@property (readwrite, copy) NSString* myString;
@end
Le compilateur est complètement pacifié en pensant que la propriété est readwrite. Je n'ai pas d'avertissement, et pas même la belle erreur de compilation "Objet ne peut pas être réglé soit en lecture seule propriété ou pas de setter trouvé" dès la mise en myString que je n'avais-je pas déclaré la readwrite propriété dans la Catégorie. Je viens d'obtenir le "Ne répond pas à sélecteur" exception à l'exécution. Si l'ajout d'ivars et de propriétés n'est pas pris en charge par (nom) Catégories, est-ce trop demander que le compilateur jouer selon les mêmes règles? Ai-je raté quelque grand de la philosophie de design?