2009-04-12 6 views
9

Ho un semplice protocollo con una proprietà:valore-chiave Osservando su un oggetto protocollo: Avvisi del compilatore on addObserver:

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

Sto aggiungendo un osservatore chiave-valore altrove per ascoltare modifiche al " si ferma" proprietà:

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

codice funziona come previsto in che ottengo eventi observeValueForKeyPath quando la 'ferma' la proprietà è cambiata. Il vero fastidio è un avviso del compilatore sulla chiamata addObserver:

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

Il metodo 'addObserver' è definito in una categoria a NSObject:

@interface NSObject(NSKeyValueObserverRegistration) 

Esiste un modo per ottenere XCode far cadere questo avvertimento ? Ho capito che i protocolli non possono adottare categorie, quindi non sono sicuro di come portare i metodi NSKeyValueObserverRegistration nel mio protocollo, a meno di copiare le dichiarazioni nel protocollo stesso, che sembra un hack.

So che questo è un problema di poco conto, in quanto è solo un avvertimento del compilatore, ma sono interessato a sapere se c'è un modo "giusto" per affrontare questo.

+2

Sede di Abizern per informazioni importanti, ma al tuo problema specifico , sostituire 'id ' con NSObject * source = ... –

risposta

12

Il vero fastidio è un avviso del compilatore sulla chiamata addObserver:

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

Il metodo 'addObserver' è definito in una categoria a NSObject:

@interface NSObject(NSKeyValueObserverRegistration) 

C'è un modo per far perdere questo XCode avvertimento?

Xcode (c minuscola) mostra solo l'avviso; è GCC, il compilatore, che ti sta dando l'avvertimento in primo luogo.

stai confondendo la classe NSObject con il protocollo NSObject. La classe NSObject è conforme al protocollo NSObject, tra gli altri, ma i protocolli non hanno alcuna relazione con le classi. Il protocollo StopsSource, essendo un protocollo, eredita dal protocollo NSObject, non dalla classe NSObject.

La dichiarazione riguarda solo questi due protocolli e non una classe specifica, quindi non include nulla al di fuori di quei protocolli che la classe NSObject può implementare (come KVO). Ecco perché ricevi l'avvertimento.

Come Jason Coco ti ha detto nel suo commento alla tua domanda, la soluzione è quella di modificare la dichiarazione di utilizzare la classe NSObject più il vostro protocollo:

NSObject <StopsSource> *source = …; 
risposta
0

Penso che potresti sentirti confuso su cosa faccia un protocollo; definisce solo un insieme di operazioni che possono essere implementate da un'altra classe.

L'unica cosa nel protocollo è una proprietà.

Inoltre, perché si sta dichiarando conforme al protocollo NSObject? Non è necessario farlo perché se si dispone di una classe che adotta il protocollo, erediterà da NSObject e quindi si conformerà a. cioè

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

I protocolli possono includere proprietà oltre ai metodi. Vedere l'esempio del protocollo MyXMLSupport in: http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF148 –

+0

I protocolli spesso si estendono da NSObject in modo che rispondano ai metodi NSObject come retain/release/respondsToSelector senza generare un avviso. Per maggiori informazioni, vedi: http://stackoverflow.com/questions/679822/why-tack-a-protocol-of-nsobject-to-a-protocol-implementation –

+0

Vedo i tuoi punti, ma se tutto quello che sei fare è mandare un singolo accettore di proprietà che dovrai creare nella classe che adotta il protocollo sembra una complicazione. – Abizern

Problemi correlati