2009-04-12 3 views
9

J'ai un protocole simple avec une propriété:-valeur clé d'observation sur un objet de protocole: Avertissements de compilation sur addObserver:

@protocol StopsSource <NSObject> 
@property (retain,readonly) NSArray * stops; 
@end 

J'ajoute un observateur clé-valeur ailleurs pour écouter les changements au " arrête » la propriété:

id<StopsSource> source = ... 
[source addObserver:self 
     forKeyPath:@"stops" 
      options:NSKeyValueObservingOptionNew 
      context:nil]; 

code fonctionne comme prévu dans ce que je reçois des événements observeValueForKeyPath lorsque la « propriété arrêts » est changé. Le véritable ennui est un avertissement du compilateur sur l'appel addObserver:

warning: '-addObserver:forKeyPath:options:context:' not found in protocol(s) 

La méthode « addObserver » est défini dans une catégorie à NSObject:

@interface NSObject(NSKeyValueObserverRegistration) 

Est-il possible d'obtenir XCode de laisser tomber cet avertissement ? Je comprends que les protocoles ne peuvent pas adopter de catégories, donc je ne suis pas sûr de savoir comment introduire les méthodes NSKeyValueObserverRegistration dans mon protocole, à moins de copier les déclarations dans le protocole lui-même, ce qui semble être un hack.

Je sais que c'est un peu un problème trivial, en ce sens que c'est juste un avertissement de compilateur, mais je suis intéressé de savoir s'il y a un "bon" moyen de résoudre ce problème.

+2

Voir Abizern des informations importantes, mais à votre problème spécifique , remplacez 'id ' par NSObject * source = ... –

Répondre

12

La véritable gêne est un avertissement du compilateur lors de l'appel de addObserver:

warning: '-addObserver:forKeyPath:options:context:' not found in protocol(s) 

La méthode 'addObserver' est définie dans une catégorie à NSObject:

@interface NSObject(NSKeyValueObserverRegistration) 

Y at-il un moyen de faire tomber XCode Attention?

Xcode (en minuscule c) vous montre simplement l'avertissement; c'est GCC, le compilateur, qui vous donne l'avertissement en premier lieu.

Vous confondez la classe NSObject avec le protocole NSObject. La classe NSObject est conforme au protocole NSObject, entre autres, mais les protocoles n'ont aucune relation propre aux classes. Votre protocole StopsSource, en tant que protocole, hérite du protocole NSObject et non de la classe NSObject. Votre déclaration ne couvre que ces deux protocoles, et non une classe spécifique, de sorte qu'elle n'inclut rien en dehors de ces protocoles que la classe NSObject peut implémenter (comme KVO). C'est pourquoi vous obtenez l'avertissement.

Comme Jason Coco vous a dit dans son commentaire sur votre question, la solution est de changer la déclaration d'utiliser la classe NSObject plus votre protocole:

NSObject <StopsSource> *source = …; 
réponse de
0

Je pense que vous pouvez être confus au sujet de ce que fait un protocole; il s'agit simplement de définir un ensemble d'opérations qui peuvent être implémentées par une autre classe.

La seule chose dans votre protocole est une propriété.

En outre, pourquoi déclarez-vous que ceci est conforme au protocole NSObject? Vous n'avez pas besoin de faire cela parce que si vous avez une classe qui adopte votre protocole, elle héritera de NSObject et sera donc conforme. à savoir

@interface YourClass : NSObject <StopSource> { 
    // etc 
@end 
+0

Les protocoles peuvent inclure des propriétés en plus des méthodes. Voir l'exemple de protocole MyXMLSupport dans: http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF148 –

+0

Les protocoles s'étendent souvent à partir de NSObject afin qu'ils répondent aux méthodes NSObject telles que retain/release/respondsToSelector sans déclencher d'avertissement. Pour plus d'informations, voir: http://stackoverflow.com/questions/679822/why-tack-a-protocol-of-nsobject-to-a-protocol-implementation –

+0

Je vois vos points, mais si tout ce que vous êtes faire est de mandater un accesseur de propriété unique que vous aurez à créer dans la classe qui adopte le protocole, il semble que trop de complication. – Abizern