2009-08-09 3 views
5

Dans Cocoa, addObserver:forKeyPath:options:context: ne conserve ni "le récepteur, ni un serveur d'observations". Par conséquent, je suppose que l'observation du soi est autorisée; qui est, il est tout à fait valable de faire quelque chose commeObservation de soi dans Cocoa

[self addObserver:self forKeyPath...]

Tant que vous vous souvenez de désenregistrer self à titre d'observateur comme la première chose à dealloc.

Cette hypothèse est-elle correcte?

Répondre

12

Oui, il n'y a pas vraiment de raison que vous ne puissiez pas vous observer. Mais comme vous l'avez dit, comme toute observation du KVO, assurez-vous de vous retirer en tant qu'observateur avant d'être libéré. Pour l'anecdote, une autre façon de procéder si vous parlez d'une simple clé est d'écrire un setter personnalisé et d'exécuter le code dont vous avez besoin dans le setter. Ce style rend un peu plus évident ce que sont les effets complets de l'appel du setter. La méthode KVO est un peu plus flexible et fonctionne avec les chemins clés qui contiennent plusieurs composants.

1

Je fais ce que Brian Webster a dit. Voici un exemple:

//.h 
... 
@property(readwrite, retain, setter=setMyPropertySynth:) id myProperty; 
-(void)setMyProperty:(id)newValue; 
.... 


//.m 
... 
@synthesize myProperty; 

-(void)setMyProperty:(id)newValue 
{ 
    //add code here 

    [self setMyPropertySynth:newValue]; 

    //add more code here 
} 
... 
+0

Ce n'est pas une bonne idée. On s'attend généralement à ce que 'obj.foo = bar;' soit équivalent à '[obj setFoo: bar];' et s'éloigner de ce modèle va dérouter les autres qui lisent/maintiennent votre code – rpetrich

+0

@rpetrich Je suis d'accord que ce n'est pas une bonne idée (j'ai écrit cette réponse il y a plus de 18 mois), mais pour une raison différente. Je n'utiliserais plus '@ synthesize'; J'écrirais maintenant tout le getter et le setter. Le fardeau supplémentaire de quelques lignes supplémentaires l'emporte sur le coût de suivre mentalement les appels de méthode supplémentaires (j'utiliserais toujours '@ property'). Je ne suis pas d'accord que les effets secondaires chez les setters (ou getters) sont intrinsèquement mauvais. Ils devraient être évités si possible. Par exemple, définir 'hypotheticalQueryObject.maxResults = 4;' pourrait légitimement déclencher une autre recherche. –

+0

@rpetrich Cela est garanti. 'obj.foo = bar;' utilise toujours l'implémentation de 'setFoo:' fournie (même si vous avez remplacé une version synthétisée). –

-1

Ne pas retirer d'observateur -dealloc. Pourquoi? Parce que quand vous allumez le garbage collector, les choses vont s'arrêter de fonctionner; -dealloc ne se fait jamais appeler. Vous devez simplement utiliser les méthodes -dealloc et -finalize pour code de nettoyage lié à la mémoire.

+0

Bon point; mais, qu'est-ce que j'utilise à la place alors? –

+0

Configurez-le simplement dans le cadre du cycle de vie de l'objet. Si la chose qui le crée indique ce qu'il faut observer, et quand arrêter de l'observer, vous injectez des dépendances, ce qui rend votre objet plus facile à réutiliser et à tester. –

+3

... mais beaucoup plus facile à utiliser de manière incorrecte, et sape la gestion de la mémoire Cocoa. Si chaque créateur doit également savoir que l'objet créé doit observer tel ou tel (en particulier si c'est lui-même), nous avons déplacé des informations privées dans l'appelant, ce qui est mauvais. Pire, si j'ai besoin d'une méthode "Détruisez-vous maintenant" qui annule cette observation, alors tout le point de GC est sorti par la fenêtre. La meilleure solution consiste à dupliquer les éléments de gestion non-mémoire dans dealloc et à les finaliser (éventuellement en les associant à une routine partagée). Cela inclut également NSNotificationCenter removeObserver. –