Tengo dos clases que pueden actuar como delegadas de una tercera clase, y ambas implementan un protocolo formal hecho completamente de métodos opcionales. Una de las clases implementa todo mientras que otra solo implementa un par de métodos que me importan. Sin embargo, en el tiempo de ejecución cuando tengo la segunda clase actúo como delegado a la tercera clase, y la tercera clase llama a uno de los métodos opcionales no implementados en ese delegado, obtengo un error de tiempo de ejecución que básicamente dice "El objetivo no responde a esto selector de mensajes ". Pensé que Object-c manejó este caso correctamente, y que simplemente no haría nada si ese método no estuviera realmente definido en la clase. ¿Podría haber algo que me falta?¿Por qué los métodos de protocolo opcional no implementados causan errores de tiempo de ejecución cuando se llama a ese método en obj-c?
Respuesta
Cuando se llama a un método opcional de su delegado, es necesario asegurarse de que responde al selector antes de llamar a:
if ([delegate respondsToSelector:@selector(optionalMethod)])
[delegate optionalMethod];
conocer los protocolos opcionales significar simplemente el objeto que implementa el protocolo no tiene que poner en práctica el método en cuestión: el destinatario debe verificar si el objeto implementa el método antes de llamar (de lo contrario, se bloqueará, como habrá notado). Estas categorías NSObject HOM pueden ser útiles:
@implementation NSObject (Extensions)
- (id)performSelectorIfResponds:(SEL)aSelector
{
if ([self respondsToSelector:aSelector]) {
return [self performSelector:aSelector];
}
return NULL;
}
- (id)performSelectorIfResponds:(SEL)aSelector withObject:(id)anObject
{
if ([self respondsToSelector:aSelector]) {
return [self performSelector:aSelector withObject:anObject];
}
return NULL;
}
@end
, entonces puede simplemente hacer:
[delegate performSelectorIfResponds:@selector(optionalMethod)];
nice suggestions :) – Kevlar
........ ¿Cuál es HOM? – bandejapaisa
HOM = Mensajes de orden superior. –
bloques podría proporcionar una mejor solución. Permiten realizar condicionalmente cualquier código basado en la existencia de una implementación de un método dado:
-(void) performBlock:(void (^)(void))block ifRespondsTo:(SEL) aSelector{
if ([self respondsToSelector:aSelector]) {
block();
}
}
Mediante el uso de esta adición a NSObject, puede ejecutar condicionalmente cualquier método @optional, no importa cuántos parámetros que podría tener .
Ver How to safely send @optional protocol messages that might not be implemented
Esta solución Bloques funciona bien, una vez que obtenga su cabeza envuelta en torno a lo que está pasando. Agregué un resultado BOOL porque quería poder ejecutar condicionalmente uno de varios métodos opcionales. Algunos consejos si está tratando de implementar esta solución:
Primero, si aún no ha encontrado extensiones/categorías, simplemente agregue esto al principio de su clase, FUERA de la definición de clase existente. Será una extensión pública o privada según el lugar donde la coloque.
@implementation NSObject (Extensions)
// add block-based execution of optional protocol messages
-(BOOL) performBlock:(void (^)(void))block ifRespondsTo:(SEL) aSelector
{
if ([self respondsToSelector:aSelector]) {
block();
return YES;
}
return NO;
}
@end
En segundo lugar, así es como usted lo llama desde el código:
BOOL b = [(NSObject*)self.delegate performBlock:^{
// code to run if the protocol method is implemented
}
ifRespondsTo:@selector(Param1:Param2:ParamN:)];
Reemplazar Param1: Param2: paramN: con los nombres de cada parámetro para el método de protocolo. Cada uno debe terminar con dos puntos. Así que si su método de protocolo se parece a:
-(void)dosomething:(id)blah withObj:(id)blah2 andWithObj(id)blah3;
la última línea se vería así:
ifRespondsTo:@selector(dosomething:withObj:andWithObj:)];
- 1. ¿Qué determina el proceso por el cual se resuelven los métodos no implementados?
- 2. Ejemplos del mundo real de los métodos de protocolo @opcional
- 3. Método de ejecución (mágico) cuando se llama el método existente
- 4. ¿Por qué UITableView llama a los métodos delegados de UIScrollView?
- 5. Método de "Agregar métodos no implementados" de Eclipse
- 6. No es seguro buscar datos de tiempo de ejecución objc
- 7. taquigrafía cuando se llama a métodos genéricos en C#
- 8. EasyMock: prueba ese método en el simulacro no se llama
- 9. ¿Por qué no se llama a Application.OnStartup?
- 10. oracle plsql: recuperar los valores de los parámetros de tiempo de ejecución cuando se llama a un procedimiento
- 11. ¿por qué textFieldDidEndEditing: no se llama?
- 12. ¿Puede un objeto de clase ObjC ajustarse a un protocolo?
- 13. ¿Por qué los inicializadores designados no están implementados en g ++
- 14. ¿Por qué no se reifican los parámetros de tipo genérico de Java en tiempo de ejecución?
- 15. ¿Por qué no se borran todos los tipos de información en Java en tiempo de ejecución?
- 16. NSURLConnection no llama a los métodos delegados
- 17. eclipse agregar métodos no implementados, incluido javadoc
- 18. método de llamada en tiempo de ejecución
- 19. ¿Cómo devolver información opcional de los métodos?
- 20. cómo cambiar los errores de tiempo de ejecución en inglés
- 21. BigO tiempo de ejecución en algunos métodos
- 22. MKMapView no llama a los métodos de delegado
- 23. Ver notificaciones de rotación: ¿por qué didRotateFromInterfaceOrientation: no se llama?
- 24. ¿Qué determina qué se escribe en un puntero de C++ cuando se llama a delete?
- 25. ¿Por qué no se llama mi filtro de acción?
- 26. método no se llama cuando se utiliza yield return
- 27. ¿Por qué se llaman los métodos no relacionados (autopostback) cuando se invoca un método Asp.Net ListBox autopostback?
- 28. ¿Por qué no se llama a mi delegado de CLLocationmanager?
- 29. ¿Qué método de actividad se llama primero?
- 30. ¿Implementando métodos abstractos en tiempo de ejecución?
me lo imaginaba, pero esperaba que no necesitaría añadir esos controles if en todo el código. Gracias por el puntero. – Kevlar