Solution de contournement pour accomplir des biens protégés en Objective-C
J'ai essayé de trouver une solution à déclarer @propriétés protégées en Objective-C, donc seules les sous-classes dans la hiérarchie peut accéder (en lecture seule, de ne pas écrire).
J'ai lu qu'il n'y a pas documenté de façon de le faire alors j'ai pensé à cette solution et je voulais vous demander StackOverflow de l'opinion à ce sujet.
Chaque classe personnalisée au sommet de la hiérarchie se compose de trois classes, une mise en œuvre et de deux interfaces.
Nommons-les:
ClassA.h
ClassA_protected.h
ClassA.m
Alors toute sous-classe de cette ClassA serait comme d'habitude:
ClassB.h
ClassB.m
J'ai d'abord créé l'interface ClassA.h où je déclare protégé variable int de sorte que toute sous-classe de la ClassA peut avoir accès:
@interface ClassA : NSObject{
@protected
int _myProtectedInt;
}
@end
Prochaine étape est la solution de contournement dont je parlais. Cependant, une fois que vous le lisez, vous verrez que c'est assez simple. J'ai déclaré une deuxième interface appelée ClassA_protected.h qui fonctionne réellement comme un extension de ClassA.h et nous permet de balise de la propriété comme readonly
:
#import "ClassA.h"
@interface ClassA ()
@property (nonatomic , readonly) int myProtectedInt;
@end
Dernière étape de la préparation de la protégée de la hiérarchie est de déclarer sa mise en œuvre dans ClassA.m où nous ne synthétiser notre propriété:
#import "ClassA_protected.h"
@implementation ClassA
@synthesize myProtectedInt = _ myProtectedInt;
@end
De cette façon, chaque classe doit être une sous-classe de ClassA.h, d'importation ClassA_protected.h à la place. Ainsi, un enfant comme, par exemple ClassB.h, serait comme suit:
#import "ClassA_protected.h"
@interface ClassB : ClassA
@end
Et un exemple de l'accès à cette propriété de ClassB.mmise en œuvre:
@implementation ClassB
-(void) method {
//edit protected variable
_myProtectedInt= 1;
//normal access
self.muProtectedInt;
}
@end
- Que faire si je importer "ClassA_protected.h" dans le permet de dire ViewController classe qui est en train d'accéder uniquement ClassB? Je peux toujours accéder à un bien protégé par ClassA par l'objet de ClassB dans votre classe principale (ici, il est ViewController classe).
Vous devez vous connecter pour publier un commentaire.
Sûr, cela fonctionne bien. Apple utilise la même approche, par exemple dans le
UIGestureRecognizer
classe. Les sous-classes doivent importer supplémentairesUIGestureRecognizerSubclass.h
fichier et remplacer les méthodes qui sont déclarées dans ce fichier.Pour de simples "propriétés" il suffit d'utiliser ivar à la place. C'est aussi bien que les propriétés à toutes fins pratiques.
En outre, la valeur par défaut est déjà protégé.
Si vous demandez des avis, voici le mien: Si l'on décide de muter votre
_myProtectedInt
il sera probablement succed de toute façon, parce que c'est certainement possible avec Objective-C runtime. Sauf cela, votre solution est tout à fait OK.
Importer les protégés d'en-tête dans la mise en œuvre uniquement. par exemple,
ClassB.h
ClassB.m
Et dans un cadre protégé de l'en-tête doit être marqué du projet de sorte qu'il n'est pas inclus dans les en-têtes publics du cadre. Apple utilisent généralement le suffixe _Internal.h pour leurs protégés méthodes.
Pour l'initialisation ou de la substitution d'un paresseux chargé obtenir la propriété que vous auriez besoin d'un accès direct à la @protégé ivar, cependant, pour votre utilisation, il serait préférable de redeclare la propriété readwrite au lieu de cela, alors vous pouvez prendre avantage de toutes les caractéristiques de l'incubateur, l'atomicité par exemple.