2012-04-09 11 views
18

C'è un modo per indicare al compilatore che un oggetto di classe è conforme a un protocollo?Un oggetto di classe ObjC può essere conforme a un protocollo?

Come comprendo, creando +(void)foo metodi di classe, un istanza di quell'oggetto classe avrà tali metodi come metodi di istanza . Quindi, finché creo i metodi +(void)foo per tutti i metodi di protocollo richiesti, posso avere un atto oggetto di classe come delegato.

Il mio problema, naturalmente, è che nel file di intestazione della classe so solo come indicare che le istanze della classe sono conformi al protocollo (come è tipicamente il caso). Quindi, il meglio che ho capito è di lanciare l'oggetto di classe in questo modo:

something.delegate = (id<SomethingDelegate>)[self class] 

Qualche idea?

correlati, ma diversi: ObjC: is there such a thing as a "class protocol"?

risposta

17

Quello che stai facendo ora è corretto in quanto attenuerà gli avvisi che è il tuo obiettivo. Si invieranno i messaggi dell'oggetto classe definiti nel protocollo per le istanze che è un po 'confuso, ma il runtime non interessa.

Pensateci in questo modo: volete impostare un delegato su un oggetto che risponde ai messaggi definiti nel protocollo. La tua classe fa questo, e la tua classe è anche un oggetto. Pertanto, dovresti trattare la tua classe come un oggetto conforme a quel protocollo. Pertanto, ciò che hai scritto è completamente corretto (in base a ciò che stai cercando di fare).

Una cosa da notare, tuttavia, è che questa classe non risponderà correttamente a conformsToProtocol:. Ciò è generalmente accettabile per l'installazione di un delegato in ogni caso (i delegati di solito non verificano se la classe è conforme allo — e controllano solo se può rispondere a un selettore).

Come nota a margine, una cosa che puoi fare è sintatticamente:

Class<SomethingDelegate> variable = (Class<SomethingDelegate>)[self class]; 

La differenza qui è che il compilatore utilizzare i metodi della classe dal protocollo, invece di messaggi di istanza. Questo non è quello che vuoi nel tuo caso, però.

+1

Ancora bisogno della sintassi del puntatore. 'Classe *'. –

+4

Non è necessaria la sintassi del puntatore. 'Class' è già un puntatore (è definito come' typedef struct objc_class * Class'. Ne avresti bisogno solo se hai bisogno di un puntatore a una classe (che è probabilmente piuttosto raro). – wbyoung

+0

Nono, intendo 'Class' come in segnaposto, non 'Class' come nel tipo effettivo. Penso di aver letto male il tuo post. –

7

Non v'è alcuna sintassi Objective-C per indicare che un metaclasse è conforme a un protocollo.

Penso che si possa farlo in fase di esecuzione, utilizzando class_addProtocol sul metaclass. Ma non l'ho provato

Immagino che potresti anche scrivere un metodo +conformsToProtocol: sulla tua classe e mentire sulla tua conformità. Ciò potrebbe avere effetti collaterali inattesi, poiché esiste già uno +conformsToProtocol: su NSObject (oltre a -conformsToProtocol:).

Nessuno di questi eliminerà la necessità di un cast per chiudere il compilatore. Basta usare un singleton.

Problemi correlati