2010-11-28 15 views

Respuesta

30

Su problema es que se ha declarado en su variable de instancia como delegado:

id<SomeProtocol> delegate; 

derecho? Bueno, eso significa que el verificador en tiempo de compilación solo buscará métodos en el protocolo <SomeProtocol>. Sin embargo, performSelector:withObject:afterDelay: se declara en NSObject. Esto significa que usted debe declarar la Ivar como:

NSObject<SomeProtocol> * delegate; 

Esto es decir que debe ser un NSObject que se ajusta a <SomeProtocol>, en contraposición a cualquier objeto que se ajusta a <SomeProtocol>. Esto debería eliminar tu advertencia, y no tienes que hacer ningún casting.

+1

¡Perfecto! ¡¡¡¡¡¡Eso es!!!!!! – SpaceDog

+0

@Dave Probablemente he aprendido más acerca de Objective-C en SO de usted más que nadie. ¡Gracias! –

+1

@Jacob eres bienvenido :) –

3

Prueba a transmitir el delegado de su clase de primer tipo, a continuación, invoque performSelector:withObject:afterDelay:

[(SomeClass *) delegate performSelector:@selector(doStuff:) withObject:myObject afterDelay:2.0]; 

Suponiendo que su delegate es de tipo id, es necesario contar el tiempo de ejecución que el objeto, de hecho, no heredan de NSObject (donde se define el método performSelector:withObject:afterDelay:) al convertirlo en el tipo de clase.

+1

Cualquier objeto heredará siempre de NSObject (todo lo hace, es una clase de raíz). Creo que te refieres a cumplir con el protocolo NSObject. –

+1

@Evan Todo * no * hereda de NSObject. Y 'performSelector: withObject: afterDelay:' is * not * defined en el protocolo 'NSObject', se define en la clase' NSObject'. –

+1

Encapsulado de rupturas de fundición. ¿Qué pasa si esto es para una clase donde el tipo de delegado es desconocido? –

2

Debe asignar el objeto delegado a la clase real que está trabajando para tener los métodos. Visto que el delegado solo puede mostrar los métodos definidos en el protocolo. performSelector: withObject: no es un método definido en el protocolo.

[(CLASS*)delegate performSelector:@selector(doStuff:) withObject:myObject afterDelay:2.0]; 
1
[NSTimer scheduledTimerWithTimeInterval:2 
    target:self 
    selector:@selector(doStuff) 
    userInfo:nil 
    repeats:NO]; 

intentar eso suponiendo que lo que desea es un temporizador

3

Aunque el elenco NSObject * que trajo Dave funcionará, hay una manera alternativa más limpia que permite que las personas usen los protocolos como es de esperar; puede hacer que el protocolo declare que es compatible con el protocolo NSObject.

NSObject no es solo una implementación sino también un protocolo que incluye todas las variantes del método performSelector :. Por lo que simplemente puede declarar en su protocolo que usted apoya NSObject como lo haría con cualquier otra clase de apoyo a un protocolo:

@protocol MyProtocol <NSObject> 

Y las advertencias del compilador se desvanecerán (suponiendo que haya importado la definición del protocolo).

Tenga en cuenta que esto significa que cualquier persona que declare que admite su protocolo tendría que ser un NSObject o heredar muchos métodos. Pero todas las clases utilizadas en la programación de iPhone se derivan de NSObject debido a consideraciones prácticas, por lo que generalmente no es un problema.

EDIT:

Resulta que el -performSelector:withObject:afterDelay: no es en el protocolo NSObject (los que no tienen el retraso son). Debido a que es aún más agradable para todos los que usan su protocolo si solo pueden usar el id para hacer referencia a un tipo de protocolo, igual usaría un protocolo para resolverlo, pero usted mismo tendría que declarar una extensión al protocolo NSObject. Por lo tanto, en el encabezado de su archivo puede agregar algo como:

@protocol MyProtocolNSObjectExtras <NSObject> 
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay; 
@end 

@protocol MyProtocol <NSObjectExtras> 
.... 
@end 

Luego obtiene los mismos beneficios que describí anteriormente.

+0

Esto no funcionaría en este caso (lo intenté), ya que el método en cuestión está definido en 'NSObject', no' ' –

+0

Aha, entiendo lo que quieres decir: vi que el protocolo era compatible con performSelector: withObject y asumí que también tenía afterDelay: ar variante de gument también ... Aún así usaría un protocolo, arreglaré mi respuesta. –

Cuestiones relacionadas