Comment puis-je utiliser objc_setAssociatedObject/objc_getAssociatedObject l'intérieur d'un objet?
Si j'utilise objc_setAssociatedObject/objc_getAssociatedObject à l'intérieur d'une catégorie de la mise en œuvre de stocker une simulation d'une variable d'instance dans une méthode de définition, comment pourrais-je accéder à la clé dans la méthode de lecture depuis toute variable déclarée dans la méthode setter serait en dehors du champ d'application de la méthode de lecture?
Edit: De préciser, si je devais utiliser le schéma suivant, où dois-je déclarer STRING_KEY pour que je puisse l'utiliser à la fois le compositeur et la méthode de lecture.
@interface NSView (simulateVar)
-(void)setSimualtedString:(NSString *)myString;
-(NSString *)simulatedString;
@end
@implementation NSView (simulateVar)
-(void)setSimualtedString: (NSString *)myString
{
objc_setAssociatedObject(self, &STRING_KEY, myString, OBJC_ASSOCIATION_RETAIN);
}
-(NSString *)simulatedString
{
return (NSString *)objc_getAssociatedObject(self, &STRING_KEY);
}
@end
Vous devez vous connecter pour publier un commentaire.
Déclarer une variable statique de sorte que vous pouvez utiliser ses adresse comme la clé.
L'appel à objc_setAssociatedObject prend un void* et uniquement l'adresse de votre variable statique est effectivement utilisé, pas le contenu d'un NSString... c'est seulement de perdre la mémoire.
Vous avez juste besoin d'ajouter:
Je sais que cette question est très vieux, mais je pense que pour être complet, il existe une autre façon d'utiliser les objets associés à la peine de mentionner. Cette solution utilise
@selector
et, par conséquent, il n'est pas nécessaire pour tout extra variable ou une constante.(inspiré par http://www.tuaw.com/2013/04/10/devjuice-better-objective-c-associated-objects/)
De stockage associés
void *
touches, j'aime cette manière de faire:Cela évite d'avoir une autre constante chaîne de caractères dans le fichier exécutable, et en fixant sa valeur à l'adresse de lui-même, vous obtenez de bons uniquing, et
const
comportement (vous aurez théoriquement obtenir un compilateur plainte si vous faites quelque chose qui allait changer la valeur de la clé), sans supplément inutile symboles exportés.Déclarer un statique (unité de compilation-champ d'application) de la variable au niveau le plus haut du fichier source. Il peut aider à le rendre plus compréhensible, quelque chose comme ceci:
Assez proche. Voici un exemple complet.
.h-fichier
.m-fichier
Comme une propriété classique accessible avec dot notation
Plus facile de syntaxe
Vous pouvez également utiliser
@selector(nameOfGetter)
au lieu de créer un pointeur statique. Pourquoi? Voir https://stackoverflow.com/a/16020927/202451. Exemple:La accepté de répondre à déjà eu droit, mais j'aimerais ajouter une explication: le point de la "clé" est d'obtenir un unique (par processus/programme) identifiant qui n'aura pas de collisions accidentelles.
Imaginer la clé est déclaré
NSUInteger
: beaucoup de gens seraient utilisation standard des valeurs comme0
,1
ou42
. Surtout si vous utilisez une bibliothèque ou d'un cadre, les collisions sont susceptibles.Donc, au lieu de cela, quelques petits malins Apple ingénieur a eu l'idée de déclarer la clé pour être un pointeur avec l'intention que vous déclarez une variable, et de transmettre le pointeur vers cette variable comme une clé. L'éditeur de liens affecter à cette variable une adresse unique au sein de votre application et ainsi vous êtes assuré d'obtenir un unique, libre de collision valeur.
En fait, vous pouvez passer une valeur que vous désirez, le pointeur n'est pas déréférencé (j'ai testé). Donc, en passant
(void *)0
ou(void *)42
que la clé fonctionne, même si ce n'est pas une bonne idée (merci donc de ne pas le faire). Pourobjc_set/getAssociatedObject
, tout ce qui importe est que la valeur passée en tant que la clé est unique au sein de votre processus/programme.