2009-09-30 9 views
5

Podría ser que yo esté haciendo el diseño incorrecto.Obteniendo que Xcode deje caer el mensaje "No se encontró el método XXX" al delegar

Estoy implementando la delegación asincrónica en una aplicación que usa NSURLConnection. Un objeto envuelve el NSURLConnection y maneja sus mensajes delegados; eso funciona bien Ahora estoy definiendo mis propios delegados en el objeto que lo utiliza (NSURLConnection mensajes ConnectionWrapper, ConnectionWrapper mensajes NeedsToUseConnection, se entiende la idea), y que funciona tan bien, sin embargo, Xcode emite esta advertencia:

n ' -request: método finishedWithResult' encontró

esto es, presumiblemente, porque estoy declarando el delegado voy a llamar así:

id<NSObject> delegate; 

... y Xcode es che lo que NSObject declara en el marco de la Fundación. Mi mensaje de delegado personalizado no está allí. Estoy adecuadamente el aislamiento de la llamada:

if([delegate respondsToSelector:@selector(request:finishedWithResult:)]) 
    [delegate request:self finishedWithResult:ret]; 

Aparte de girar la advertencia fuera - Me gusta trabajar con tantas advertencias en lo posible - hay una manera de comunicarse (ya sea sintácticamente o por medio de una directiva de compilación) que soy consciente de que este mensaje no está declarado? ¿Debería, en cambio, utilizar un patrón de diseño de interfaz para este a la Java? ¿Usando id<WillReceiveRequestMessages> o algo?

Abierto a sugerencia.

Respuesta

10

Una mejor manera de hacerlo sería crear su propio protocolo de delegado:

@protocol MyControlDelegate <NSObject> 

@optional 
- (void)request:(MyControl *)request didFinishWithResult:(id)result; 

@end 

Entonces, le declare su delegado como esto:

id <MyControlDelegate> delegate; 

El compilador ya no se quejan cuando se escribe esto:

if ([delegate respondsToSelector:@selector(request:didFinishWithResult:)]) 
    [delegate request:self didFinishWithResult:result]; 

La sintaxis es <NSObject> importa nt en la definición de protocolo porque le dice al compilador que incorpore el protocolo NSObject. Así es como su protocolo obtiene métodos como respondsToSelector:. Si dejó eso, el compilador empezaría a quejarse sobre respondsToSelector: en su lugar.

+1

Gracias. Acabo de ver un ejemplo de eso con UIAlertViewDelegate, y eso es muy útil. –

0

Esto es, presumiblemente, porque estoy declarando el delegado estoy llamando así: ... y Xcode está comprobando lo NSObject declara en el marco de la Fundación .

Eso es incorrecto. Si ese fuera el caso, entonces recibirías una advertencia sobre el objeto "puede que no responda" al método, o algo así. Este es un problema completamente separado.

Esta advertencia se debe al hecho de que el compilador debe conocer la firma de un selector para llamarlo. Esto se debe a que, detrás de escena, el compilador traduce una llamada de método a objc_msgSend o objc_msgSend_stret dependiendo de si el método devuelve struct o no.Si no conoce el tipo de devolución, adivinará que no es un struct, y usará la primera función. Sin embargo, esto podría estar mal.

La solución es tener el método declarado en cualquier lugar en absoluto. Ni siquiera tiene que ser declarado en la clase correcta. Puede declararlo en algún protocolo ficticio que nunca se use. Siempre y cuando se declare en algún lugar, el compilador sabrá y podrá compilarlo correctamente.

Cuestiones relacionadas