2009-04-12 7 views
9

que tienen un protocolo sencillo con una propiedad:valor-clave Observando en un objeto de protocolo: Advertencias del compilador en addObserver:

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

estoy añadiendo un observador clave-valor en otro lugar para escuchar a los cambios a la " paradas" propiedad:

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

código funciona como se espera en que se añaden eventos observeValueForKeyPath cuando el 'paradas' propiedad se cambia. La molestia real es una advertencia del compilador en la llamada addObserver:

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

El método 'addObserver' se define en una categoría a NSObject:

@interface NSObject(NSKeyValueObserverRegistration) 

¿Hay alguna manera de obtener XCode para dejar esta advertencia ? Tengo entendido que los protocolos no pueden adoptar categorías, por lo que no estoy seguro de cómo incorporar los métodos NSKeyValueObserverRegistration en mi protocolo, salvo copiar las declaraciones en el protocolo mismo, lo que parece un truco.

Sé que este es un problema un tanto trivial, en el sentido de que es solo una advertencia del compilador, pero me interesa saber si existe una forma "correcta" de solucionarlo.

+2

Sede de Abizern para obtener información importante, pero a su problema específico , reemplace 'id ' con NSObject * source = ... –

Respuesta

12

La molestia real es una advertencia del compilador en la llamada addObserver:

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

El método 'addObserver' se define en una categoría a NSObject:

@interface NSObject(NSKeyValueObserverRegistration) 

¿Hay alguna manera de hacer que XCode deje esto? ¿advertencia?

Xcode (c minúscula) solo le está mostrando la advertencia; es GCC, el compilador, que te está dando la advertencia en primer lugar.

estás confundiendo la clase NSObject con el protocolo NSObject. La clase NSObject se ajusta al protocolo NSObject, entre otros, pero los protocolos no tienen relación propia con las clases. Su protocolo StopsSource, al ser un protocolo, hereda del protocolo NSObject, no de la clase NSObject.

Su declaración solo cubre esos dos protocolos, y no cualquier clase específica, por lo que no incluye nada fuera de los protocolos que la clase NSObject puede implementar (como KVO). Es por eso que recibes la advertencia.

Como Jason Coco le dijo en su comentario sobre tu pregunta, la solución es cambiar la declaración de utilizar la clase NSObject además de su protocolo:

NSObject <StopsSource> *source = …; 
respuesta
0

Creo que puede estar confundido acerca de lo que hace un protocolo; solo define un conjunto de operaciones que pueden ser implementadas por otra clase.

Lo único en su protocolo es una propiedad.

Además, ¿por qué declara que esto se ajusta al protocolo NSObject? No necesita hacer esto porque si tiene una clase que adopta su protocolo, heredará de NSObject, y así se conformará a. es decir

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

Los protocolos pueden incluir propiedades además de los métodos. Consulte el ejemplo del protocolo MyXMLSupport en: http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF148 –

+0

Los protocolos a menudo se extienden desde NSObject para que respondan a los métodos de NSObject como retener/liberar/responder al selector sin generar una advertencia. Para obtener más información, consulte: http://stackoverflow.com/questions/679822/why-tack-a-protocol-of-nsobject-to-a-protocol-implementation –

+0

Veo sus puntos, pero si todos son hacer es ordenar un único acceso a la propiedad que tendrá que crear en la clase que adopta el protocolo, parece una supercomplicación. – Abizern

Cuestiones relacionadas