2012-03-06 9 views
32

Implementé un protocolo con un método opcional y en el método de llamada deseo enviar respondsToSelector: a self.delegate antes de enviar el mensaje, pero eso no se compila. El mensaje de error es:self.delegate respondsToSelector: ... no compila

No Método de instancia conocido para el selector 'respondsToSelector'.

Como solución alternativa, que "saneadas" el delegado como se muestra a continuación, que recopila ...

//MyClass.h: 

@class MyClass; 

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

@interface MyClass : UIViewController 

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

@end 

y

//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]; 
} 

.

Revisé una serie de publicaciones, entre ellas this one, pero no responde al problema de compilación fallida.

Además, descriptores de acceso alternativas no funcionan ...

[self delegate] 
//or 
_delegate 

Alguien ha visto esto o puede aconsejar una mejor manera de manejar?

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

Respuesta

95

-respondsToSelector: es un método en NSObject. O bien asumir que su id delegado es de hecho un NSObject, y echarlo:

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

O, mejor, hacer su delegado explícitamente un NSObject:

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

O hacen ser el protocolo un sub-protocolo de NSObject:

@protocol MyClassDelegate <NSObject>

+10

Ka-ching ... Tomaré la puerta n. ° 3. – vmanjz

+0

¡Declarando que el delegado como NSObject funcionó, gracias! – c0d3Junk13

14

Básicamente, usted está diciendo que su delegado está limitado solamente por su protocolo de <MyClassDelegate> por lo que el compilador supone que esos son los únicos métodos disponibles. Lo que hay que hacer es tener el protocolo extender <NSObject> así:

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

De esa manera el compilador sabe que cualquier objeto que se ajuste a su protocolo también cumpla con el protocolo que define <NSObject>respondsToSelector:.

+1

Sí, la finalización del código aconseja lo mismo ... práctica estándar a partir de ahora. – vmanjz

Cuestiones relacionadas