2009-04-20 14 views
21

Es posible declarar implementaciones anónimas de elementos como Delegados en Objective-C. Creo que tengo el derecho de terminología, pero aquí hay un ejemplo de Java:Implementación de delegado anónimo en Objective-C?

myClass.addListener(new FancyInterfaceListener({ 
    void onListenerInterestingAction(Action a){ 
     ....interesting stuff here 
    } 
}); 

Así por ejemplo, para gestionar una llamada UIActionSheet tengo que declarar otro método en la misma clase, que parece un poco tonto si quiero pasar Datos, porque tendría que almacenar esos datos como una variable global. Aquí está un ejemplo de la eliminación de algo con un diálogo de confirmación que le pregunta si su seguro:

-(void)deleteItem:(int)indexToDelete{ 
    UIActionSheet *confirm = [[UIActionSheet alloc] initWithTitle:@"Delete Item?" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Delete" otherButtonTitles:nil]; 
    [confirm showInView:self.view]; 
    [confirm release]; 
} 

y la UIActionSheetDelegate en la misma clase:

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ 
    if (buttonIndex == 0){ 
     [[Settings sharedSettings] removeItemAtIndex:/*need index variable here*/]; 
     [drinksTable reloadData]; 
    } 
} 

Lo que yo quiero ser capaz de hacer es declarar en línea , tal como lo hice en el ejemplo de Java en la parte superior. es posible?

+0

Acabo de escribir una posible solución para este tipo de situaciones [aquí] (https://github.com/GojaN/AnonymusDelegate). Tenga en cuenta que esta es una prueba de concepto. –

+0

Sí, puede hacerlo con bibliotecas de terceros, lea mi respuesta completa aquí: http://stackoverflow.com/a/33096839/440168 – k06a

Respuesta

17

Actualmente, no hay forma de hacerlo en Objective-C. Apple ha publicado algunos trabajos sobre sus esfuerzos para agregar bloques (realmente más como cierres lambda que clases anónimas) al lenguaje. Es probable que puedas hacer algo similar al delegado anónimo con ellos.

Mientras tanto, la mayoría de los programadores de Cocoa agregan los métodos de delegado a una categoría separada en la clase de delegado. Esto ayuda a mantener el código más organizado. En el archivo .m para la clase en su ejemplo, me gustaría hacer algo como esto:

@interface MyClass (UIActionSheetDelegate) 
- (void)actionSheet:(UIActionSheet*)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex; 
@end 

@implementation MyClass 
//... normal stuff here 
@end 

@implementation MyClass (UIActionSheetDelegate) 
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ 
    if (buttonIndex == 0){ 
     [[Settings sharedSettings] removeItemAtIndex:/*need index variable here*/]; 
     [drinksTable reloadData]; 
    } 
} 
@end 

emergente método de Xcode en la ventana del editor puede separar declaración y aplicación de la categoría de la clase principal.

+0

¿Necesita tener la declaración de interfaz para cada protocolo que implemente? Si es así, eso es mucho más trabajo.(Nunca he declarado los métodos en un protocolo implementado en mi interfaz, bajo la premisa de que simplemente declarar el protocolo "implementado" era suficiente). –

+1

No, puede declarar múltiples protocolos, solo use una coma en la interfaz. Además, la mayoría del código que he visto, en lugar de usar una categoría como esta (esta no es la función para la que está diseñada la función, está diseñada para permitirle extender clases a las que no tiene implementada la implementación sin crear subclases), simplemente separa el código en su propia sección en el archivo con la directiva '#pragma mark'. –

4

Objective-C no tiene una noción de clases anónimas como las de Java, por lo que no puede crear una clase "en línea" como en el código de Java.

+0

Bastante, así que hay alguna manera de hacer esto de manera más elegante que crear otro método ¿en la misma clase? ¿Qué pasa si quiero dos UIActionSheets diferentes? – rustyshelf

+0

Para dos hojas de acción usaría la propiedad de etiqueta para ver cuál llamó el método de delegado. Si te metes en muchas situaciones como esta, creo que la responsabilidad de ese controlador puede ser demasiado grande. No hay nada más elegante que la forma en que lo tienes. Tienes que hacer un seguimiento del índice del artículo por ti mismo hasta donde yo sé. – Jab

1

Creo que las clases anónimas se pueden implementar en Objective-C, pero tomará mucha NSProxy magia y IMP locura. Este es uno de mis proyectos actuales.

2

Estaba buscando algo diferente cuando me encontré con esto, pero si haces una búsqueda de UIALERTVIEW + BLOCKS encontrarás varios hits para hacer UIALERTVIEWs en línea. Este es el que he estado usando: ALERTVIEW w/blocks

0

¿Qué tal una clase implementando la interfaz de delegado? En la inicialización tomaría un bloque. En la definición de delegado llama a este bloque.

Esto permite que varias hojas UIActionSheets existan simultáneamente sin tener que comparar en identidad.

Cuestiones relacionadas