2011-09-22 15 views

risposta

22

È semplicemente lo stesso concetto ereditarietà per le classi. Se un protocollo adotta un altro protocollo, "eredita" i metodi dichiarati di questo protocollo adottato.

Il protocollo NSObject dichiara in particolare metodi come respondsToSelector:. Quindi questo è particolarmente utile se si dichiara un @protocol che ha metodi @optional, perché quando si chiameranno i metodi su oggetti conformi a questo protocollo, sarà necessario verificare se l'oggetto risponde al metodo prima di chiamarlo se questo metodo è facoltativo.


@protocol SomeProtocol <NSObject> 
-(void)requiredMethod; 
@optional 
-(void)optionalMethod; 
@end 

@interface SomeObject : NSObject 
-(void)testMyDelegate; 
@property(nonatomic, assign) id<SomeProtocol> myDelegate; 
@end 

@implementation SomeObject 
@synthesize myDelegate 

-(void)testMyDelegate { 
    // Here you can call requiredMethod without any checking because it is a required (non-optional) method 
    [self.myDelegate requiredMethod]; 

    // But as "optionalMethod" is @optional, you have to check if myDelegate implements this method before calling it! 
    if ([myDelegate respondsToSelector:@selector(optionalMethod)]) { 
     // And only call it if it is implemented by the receiver 
     [myDelegate optionalMethod]; 
    } 
} 
@end 

Lei sarà solo in grado di chiamare respondsToSelector su myDelegate se myDelegate è dichiarato come un tipo che implementa respondsToSelector (in caso contrario si avrà alcuni avvisi). Ecco perché il protocollo <SomeProtocol> deve adottare se stesso il protocollo <NSObject>, che a sua volta dichiara questo metodo.

Si può pensare di id<SomeProtocol> come "qualsiasi oggetto, di qualsiasi tipo (id), si deve solo implementare i metodi dichiarati nel SomeProtocol, compresi i metodi dichiarati nel protocollo genitore NSObject. Così può essere un oggetto di qualsiasi digitare ma perché SomeProtocol adotta il protocollo NSObject in sé, è garantito che si è permesso di chiamare respondsToSelector su questo oggetto, che consente di controllare se l'oggetto implementa un dato metodo prima di chiamare se è facoltativa.


Si noti inoltre che non è possibile effettuare SomeProtocol adotta il protocollo NSObject e dichiarare invece la variabile come id<SomeProtocol,NSObject> myDelegate in modo che sia ancora possibile chiamare respondsToSelector:. Ma se lo fai che sarà necessario dichiarare tutte le variabili in questo modo in tutto il mondo si utilizza questo protocollo ... Quindi questo è molto più logico per rendere SomeProtocol adottare direttamente il protocollo NSObject;)

+2

Si noti che il fatto che il protocollo originale sia conforme a 'NSObject' non è strettamente necessario per evitare avvisi. Invece di usare 'id myDelegate', usa' NSObject * myDelegate'. –

+1

Sì, anche questa può essere una soluzione. Ma inserisce una dipendenza dai tipi (anche se è improbabile che ciò accada, alcuni potrebbero usare NSProxy o qualsiasi altra cosa: sono d'accordo che questo è raro e raro, ma comunque), quindi in qualche modo viola il principio di obiezione del OOP. Se non vi è alcun motivo per costringere l'utente a utilizzare una classe che eredita esplicitamente NSObject, ma invece è solo necessario implementare alcuni metodi, perché forzarlo ...l'approccio corretto è quindi quello di utilizzare il protocollo 'NSObject' e il tipo' id ', non il tipo NSObject, per mantenere collegamenti deboli tra i tipi ed evitare una tipizzazione forte. – AliSoftware

2

Inheritance ...................

+3

Interface Inheritance, più precisamente. – bbum

+1

Hai ragione, ma volevo l'eleganza. –

Problemi correlati