6
votes

Comment fournir une mise en œuvre personnalisée supplémentaire des méthodes d'accesseur lors de l'utilisation de @synthesize?

Je veux déclencher du code lorsqu'une propriété est accessible et modifiée. J'utilise @property code> et @synthesize code> dans mon code pour mes ivars. Les propriétés sont conservées, donc je voudrais garder cette gestion de la mémoire générée automatiquement par @synthesize code>.

Cependant, je suppose que @synthesize code> indique au compilateur de Générer le code de méthodes d'accesseur à droite où @synthesize est code>, donc la plupart des cas en haut du code, non? p>

et quand j'ai une propriété FOO , je reçois -Setfoo code> et -foo code> méthodes. Puis-je simplement faire une méthode comme celle-ci, pour exécuter un autre code personnalisé lorsqu'une propriété est modifiée? P>

-(void)setFoo {
    // custom stuff
}


0 commentaires

4 Réponses :


1
votes

Si vous fournissez une implémentation implémentée pour les Setteurs ou les getters, cela utilisera cela au lieu de la mise en œuvre générée. Il n'est pas difficile de mettre en œuvre l'aspect "Conservation" des getters et des setters générés par le compilateur lorsque vous synthétisez, vous pouvez donc écrire vos propres getters et setters que je dirais et aller avec ça.


0 commentaires

-2
votes

Oui, dans votre déclaration de @property, vous pouvez spécifier les méthodes Getter et Setter.

@property (readwrite,getter=privateGetFoo,setter=privateSetFoo:) NSObject * foo;


2 commentaires

Vous avez dit: "Dans votre foo et votre setfoo: méthodes ..." Alors que [OBJ Setfoo: X] et [Obj Foo] sont disponibles, il est important de noter qu'en raison de la propriété modifiée, obj.foo ne sera pas disponible pour Écrire, et vous devrez utiliser obj.setfoo = x. Ce n'est pas la façon dont @Property le fait normalement, où obj.foo est utilisé pour la lecture et l'écriture.


Ensuite, Objet.foo équivaut à [objet privéfoo], qui défait tout le but d'utiliser des propriétés.



5
votes

Vous pouvez utiliser @property et @synthesize comme vous le feriez normalement, mais fournissez un seigteur personnalisé ou un getter (ou les deux) et ceux-ci seront utilisés à la place. Typiquement, je ferai quelque chose comme ceci: xxx

Lorsque j'utilise la propriété définie, elle invoquera ma méthode personnalisée. Cependant, le get sera toujours synthétisé.


7 commentaires

FYI, votre exemple Setter a un bogue, dans celui qui l'appelait deux fois avec le même objet peut entraîner une distribution de cet objet avant sa conservation. Pas une très grosse affaire, mais il montre à quel point il peut être difficile de bien comprendre ces choses.


Je ne suis pas sûr de suivre, pourriez-vous expliquer comment il devrait être écrit à la place (ce n'est pas que je ne vous croyais pas, j'aimerais savoir comment le faire correctement). Merci :)


Oh, NVM je vois le problème, je vais le mettre à jour pour refléter les changements.


Une autre façon qui évite la déclaration de si: [ANAME Conserver]; [libération de nom]; Nom = aname;


Est-ce que la déclaration si plus rapide? Il s'agit juste de comparer deux pointeurs et éventuellement de retourner tôt. Où l'alternative appelle les deux méthodes, puis assigne-t-elle peu importe? (Je sais que ce n'est pas vraiment une grosse affaire à long terme)


Habituellement, lorsque nous appelons un poste de jeu: objet, l'objet devrait avoir un nombre de retenue de> 1 droite? Je veux dire de l'appelant POV, ils ne devraient pas donner à un autre objet quelque chose avec un retenue de zéro, non? (La libération doit être appelée après définit quand même), donc je pense [publication de nom]; Nom = [Aname Conserver]; devrait être très bien dans la plupart des cas.


Est-ce que cela retient / libération de shuffle de libération toujours nécessaire sous arc? Et existe-t-il une autre magie que le setter synthétisé pourrait faire (comme avec tous les différents modificateurs tels que fort et nonatomic et ce que nous devrions imiter?



0
votes

Une solution wacky consiste à créer une super classe abstraite qui vous donne la synthèse de la propriété normale. Ensuite, créez une sous-classe concrète que vous utiliserez réellement, et cela implémente et une méthode de remplacement (même signature) et appelle super pour faire le réglage réel. Cela vous permet de faire ce que vous voulez faire avant ou après l'appel à la mise en œuvre de Super.

Exemple: p> xxx pré>

rien d'autre nécessaire dans le fichier .m au-delà du fichier. Pour ce test. p>

Créez la sous-classe, rien ne nécessitait spécialement dans le @interface P> xxx pré>

dans l'@Implementatation que nous faisons notre substitution. P>

    ALTOClassAJunior *aCAJ = [ALTOClassAJunior new];
NSLog(@"aCAS.catName %@", aCAJ.catName);

NSLog(@"set it to George.");

[aCAJ setCatName:@"George"];

NSLog(@"aCAS.catName %@", aCAJ.catName);


0 commentaires