2010-09-22 9 views
16

Quiero establecer el delegado de un objeto dentro de un método de clase en Objective-C. Pseudocódigo:Objective-C equivalente a las clases anónimas de Java en los métodos de clase

+ (ClassWithDelegate*) myStaticMethod { 
    if (myObject == nil) { 
     myObject = [[ClassWithDelegate alloc] init]; 
     // myObject.delegate = ? 
    } 
    return myObject; 
} 

En Java simplemente crearía una clase anónima que implementara el protocolo de delegado. ¿Cómo puedo hacer algo similar en Objective-C?

Básicamente me gustaría evitar crear una clase (y archivos) separada para implementar un protocolo simple de delegado.

+0

posible duplicado de [? Delegado aplicación Anonymous en Objective-C] (http://stackoverflow.com/questions/766475/anonymous-delegate-implementation-in- objetivo-c) –

+0

@Dave DeLong Título aclarado para diferenciar de esa pregunta. En este caso, el contexto es un método estático. – hpique

+0

el contexto no importa. Debe proporcionar un objeto ('id') como delegado, y la otra pregunta responde claramente que no existe una clase anónima en Objective-C (todavía), por lo que tendrá que usar un objeto normal –

Respuesta

13

Actualmente no hay clases anónimas en Objective-C.

A menudo puede utilizar un objeto ya existente. Por ejemplo, para un NSTableViewDataSource, puede implementar los métodos en el documento o ver el controlador y pasarlo como delegado.

O puede hacer que el objeto implemente el protocolo y lo convierta en su propio delegado en el caso predeterminado.

O los métodos que envían los mensajes de delegado pueden buscar un delegado nulo y hacer algo sensato en esa situación.

O puede declarar y definir una clase dentro del archivo de implementación que está creando el objeto que necesita un delegado.

+0

Gracias JeremyP! Entonces, básicamente, en este caso podría definir una clase ad-hoc en el archivo de implementación, crear una instancia en el mensaje de la clase y asignarla como delegado. ¿Sería eso correcto? – hpique

+0

Esa es probablemente la forma correcta de hacerlo en esta situación. – JeremyP

16

Como JeremyP correctamente ha dicho, No hay clases anónimas en el Objetivo C como las hay en Java.

Pero en Java, las clases anónimas se utilizan principalmente para implementar la interfaz de método único o lo que también llamamos interfaz funcional .

lo hacemos para evitar tener que implementar la interfaz en una clase sólo para una implementación del método que se usa más comúnmente para oyentes, observadores y controladores de eventos.

Esto se hace sobre todo debido a la falta de funciones de primera clase anónima en Java (antes de la versión 8 y lambda proyecto).

Objective C tiene algo que se llama como bloques, donde se puede pasar directamente a un bloque que contiene la aplicación de dicho método único en lugar de una clase vacía envolviéndolo.

Ejemplo:

Un uso de Clase Anonymous en Java

//Functional interface 
interface SomethingHandler 
{ 
    void handle(Object argument); 
} 

//a method that accepts the handler in some other class 
class SomeOtherClass 
{ 
    void doSomethingWithCompletionHandler(SomethingHandler h){ 
     // do the work that may consume some time in a separate thread may be. 
     // when work is done call the handler with the result which could be any object 
     h.handler(result); 
    }; 
} 

// Somewhere else in some other class, in some other code 
// passing the handler after instantiating someObj as an object of SomeOtherClass which can use the handler as needed 
SomeOtherClass someObj = new SomeOtherClass(); 
someObj.doSomethingWithCompletionHandler(new SomethingHandler() 
         { 
           void handle(Object argument) 
           { 
           // handle the event using the argument 
           } 
         }); 

En C Objetivo

// declare the handler block 
typedef void (^SomethingHandler)(id argument){} 

// this interface is different than Java interface which are similar to Protocols 
@interface SomeOtherClass 
-(void)doSomethingWithCompletionHandler:(SomethingHandler)h; 
@end 

@implementation SomeOtherClass 
-(void)doSomethingWithCompletionHandler:(SomethingHandler)h 
{ 
      // do the work that may consume some time in a separate thread may be. 
      // when work is done call the handler with the result which could be any object 
      h(result); 
} 

@end 

    // passing the handler after instantiating someObj as an object of SomeOtherClass which can use the handler as needed 

SomeOtherClass* someObj = [[SomeOtherClass alloc] init]; // ARC :) 

[someObj doSomethingWithCompletionHandler:^(id argument) 
              { 
               // handle the event using the argument 
              }]; 
1

clases anónimos pueden ser implementados con biblioteca.Hace varios meses trabajé en la horquilla MMMutableMethods para mejorar la implementación anterior (discutiendo con el autor) y agregar mi propio mecanismo sin ninguna manipulación obj-c en tiempo de ejecución.

https://github.com/k06a/MMMutableMethods

A. En primer mecanismo funciona en obj-c tiempo de ejecución de creación de clases:

MM_CREATE(MM_REUSE,^(Class class){ 
    [class addMethod:@selector(onResultWithId:) 
     fromProtocol:@protocol(AMCommandCallback) 
      blockImp:^(id this,id res){ 
       NSLog(@"onResultWithId: %@",res); 
      }]; 
    [class addMethod:@selector(onErrorWithJavaLangException:) 
     fromProtocol:@protocol(AMCommandCallback) 
      blockImp:^(id this,JavaLangException *e){ 
       NSLog(@"onErrorWithJavaLangException: %@",e); 
      }]; 
}) 

B. Segundo mecanismo funciona en el mensaje simple aplicación hacia adelante:

MM_ANON(^(MMAnonymousClass *anon){ 
    [anon addMethod:@selector(onResultWithId:) 
     fromProtocol:@protocol(AMCommandCallback) 
      blockImp:^(id this,id res){ 
       NSLog(@"onResultWithId: %@",res); 
      }]; 
    [anon addMethod:@selector(onErrorWithJavaLangException:) 
     fromProtocol:@protocol(AMCommandCallback) 
      blockImp:^(id this,JavaLangException *e){ 
       NSLog(@"onErrorWithJavaLangException: %@",e); 
      }]; 
}) 
crea

Primero uno nuevas clases obc-j en tiempo de ejecución, le permite crear clases MM_CREATE_CLASS(MM_REUSE, *) y directamente instancias con MM_CREATE(MM_REUSE, *). Las clases se crearán solo en la primera ejecución y se reutilizarán de manera predeterminada, pero puede evitar la reutilización llamando al MM_CREATE_CLASS_ALWAYS(*) y MM_CREATE_ALWAYS(*).

El segundo mecanismo no crea ninguna instancia de tiempo de ejecución, simplemente recuerda los bloques para los selectores y les envía las llamadas a métodos.

Prefiero la segunda manera de no crear muchas clases en tiempo de ejecución. En mi humilde opinión, es mucho más seguro y poderoso.

Para utilizar esta biblioteca simplemente:

pod 'MMMutableMethods', :git => 'https://github.com/k06a/MMMutableMethods' 
Cuestiones relacionadas