2012-03-06 13 views
32

Ho implementato un protocollo con un metodo opzionale e nel metodo di chiamata voglio inviare respondsToSelector: a self.delegate prima di inviare il messaggio, ma che non viene compilato. Il messaggio di errore è:self.delegate respondsToSelector: ... non compilare

Nessun metodo di istanza noto per il selettore 'respondsToSelector'.

Come un work-around, I "Sanitized" il delegato come mostrato di seguito, che compila ...

//MyClass.h: 

@class MyClass; 

@Protocol MyClassDelegate 
- (void)myClass:(MyClass *)sender willDoSomething:(BOOL)animated; 
@end 

@interface MyClass : UIViewController 

@property (nonatomic, weak) id<MyClassDelegate> delegate; 

@end 

e

//MyClass.m: 

... 
@synthesize delegate = _delegate; 
... 

id sanitizedDelegate = self.delegate; //Hmmmm... why does this work? 

if ([sanitizedDelegate respondsToSelector:@selector(myClass:willDoSomething:)]) { 
    [self.delegate myClass:self willDoSomething:animated]; 
} 

.

Ho controllato un numero di post compreso this one ma non risponde al problema di compilazione non riuscita.

Inoltre, funzioni di accesso alternativi non funzionano ...

[self delegate] 
//or 
_delegate 

qualcuno ha visto questo o può consigliare un modo migliore di gestire?

IOS 5.0: (9A334), Xcode 4.2.1 (4D502)

risposta

95

-respondsToSelector: è un metodo su NSObject. O supporre che il vostro id delegato è in realtà un NSObject, e gettalo via:

[(NSObject*)self.delegate respondsToSelector:@selector(myClass:willDoSomething:)]

O, meglio, rendere il vostro delegato esplicitamente un NSObject:

@property (nonatomic, weak) NSObject<MyClassDelegate>* delegate;

o fare il protocollo sia un sub-protocollo di NSObject:

@protocol MyClassDelegate <NSObject>

+10

Ka-ching ... Prenderò la porta # 3. – vmanjz

+0

Dichiarare il delegato come NSObject ha funzionato, grazie! – c0d3Junk13

14

In pratica lei sta dicendo che il delegato è limitata solo dalla vostra protocollo <MyClassDelegate> in modo che il compilatore presuppone che questi sono gli unici metodi disponibili. Quello che dovete fare è avere il protocollo di estendere <NSObject> in questo modo:

@Protocol MyClassDelegate <NSObject> 
- (void)myClass:(MyClass *)sender willDoSomething:(BOOL)animated; 
@end 

In questo modo il compilatore sa che qualsiasi oggetto che si conforma al vostro protocollo è inoltre conforme al protocollo <NSObject> che definisce respondsToSelector:.

+1

Sì, il completamento del codice consiglia la stessa ... pratica standard d'ora in poi. – vmanjz