2012-01-06 13 views

risposta

13

Si fa riferimento come:

id<TheNameOfTheProtocol> aVariableToThatProtocol; 

Oppure, se un messaggio vuole un oggetto (Protocol *):

[myObject conformsToProtocol:@protocol(TheNameOfTheProtocol)]; 
+0

Solo per curiosità, alcuna ragione per cui un protocollo "tipo" deve essere utilizzato con un "id ?" Provenendo da uno sfondo C#, è un po 'più facile visualizzare un riferimento all'interfaccia poiché si tratta solo della sua dichiarazione simile a un riferimento di classe (cioè protocollo IProtocollo;). – 5StringRyan

+0

@ 5StringRyan Non conosco il ragionamento, ma il tipo 'id' è il tipo generale per qualsiasi oggetto, anche se non è un NSObject. Un vantaggio di questa sintassi è che consente più protocolli. Puoi fare qualcosa sulla falsariga di 'id ' per esprimere che l'oggetto è conforme a entrambi i protocolli. Oppure, se il tuo protocollo non è conforme a NSObject, ma un'istanza di classe a cui fai riferimento, puoi fare quanto segue: 'id '. –

+3

@ 5StringRyan il tipo non * deve * essere 'id'. esempio: 'NSArray * var = [array NSArray];' è sicuramente utile a volte. puoi anche scrivere 'NSArray * var = [array NSArray];' mooolto ... è sicuramente un buon modo per iniettare un po 'di sicurezza. (gli esempi sono stupidi - dimostrano solo la sintassi) – justin

4

id <YourProtocol> delegate (che viene utilizzato per fare riferimento al protocollo)?

ho fatto riferimento alla mela del funzionario DOC, e ha trovato un esempio semplice per riferimento ad altri protocolli in un protocollo:

#import "B.h" 

@protocol B; // To break the recursive cycle, you must use the @protocol directive to make a forward reference to the needed protocol instead of importing the interface file where the protocol is defined 

@protocol A 
    - foo:(id <B>)anObject; 
@end 

in cui il protocollo B è dichiarato così:

#import "A.h" 

@protocol B 
    - bar:(id <A>)anObject; 
@end 

Si noti che l'uso della direttiva @protocol in questo modo informa semplicemente il compilatore che B è un protocollo da definire in seguito. Non importa il file di interfaccia in cui è definito il protocollo B.


E here're più che cosa vorresti sapere su :

In molti modi, i protocolli sono simili a definizioni di classe. Entrambi dichiarano i metodi e in fase di esecuzione sono entrambi rappresentati da classi di oggetti per istanze di Class e protocolli per istanze di Protocollo. Come gli oggetti classe, gli oggetti protocollo vengono creati automaticamente dalle definizioni e dalle dichiarazioni trovate nel codice sorgente e vengono utilizzati dal sistema runtime. Non sono allocati e inizializzati nel codice sorgente del programma.

codice sorgente può fare riferimento a un oggetto di protocollo utilizzando la direttiva @protocol() -la stessa direttiva che dichiara un protocollo, solo che qui si ha una serie di parentesi finali. Le parentesi racchiudono il nome del protocollo:

Protocol *myXMLSupportProtocol = @protocol(MyXMLSupport); 

Solo in questo modo che il codice sorgente può evocare un oggetto protocollo. Diversamente da un nome di classe, un nome di protocollo non designa l'oggetto, tranne all'interno di @protocol().


E per di più, il è possibile verificare se un oggetto è conforme a un protocollo con l'invio di un messaggio conformsToProtocol::

if (! [receiver conformsToProtocol:@protocol(MyXMLSupport)] ) { 
    // Object does not conform to MyXMLSupport protocol 
    // If you are expecting receiver to implement methods declared in the 
    // MyXMLSupport protocol, this is probably an error 
} 

Il conformsToProtocol: prova è come il risponde aSelettore: test per un singolo metodo, tranne che verifica se un protocollo è stato adottato (e presumibilmente tutto il metodi che dichiara implementati) piuttosto che se sia stato implementato un particolare metodo. Perché controlla tutti i metodi nel protocollo, conformsToProtocol: può essere più efficiente di respondsToSelector:.

Il conformsToProtocol: test è anche come le isKindOfClass: prova, tranne che verifica per un tipo basato su un protocollo piuttosto che un tipo basato sulla gerarchia di ereditarietà.

2

E 'lo stesso che su OS X:

Protocol * p = objc_getProtocol("UITableViewDataSource"); 

E' dichiarato nel <objc/runtime.h>:

typedef struct objc_object Protocol; 
Problemi correlati