2009-07-08 20 views
5

En una palabra, ¿cómo?Métodos de instancia llamando a métodos de clase llamando a los métodos de instancia

Tengo un controlador de vista que crea algunos objetos personalizados. Uno de esos objetos necesita volver a llamar a un método en el controlador. El objeto parece querer llamar a un método de clase en el controlador, lo que podría estar bien, excepto que la clase en el controlador necesita llamar a un método de instancia en el controlador, y no parece querer hacer eso. ¿Tiene sentido?

Si no es así, aquí está pseudo código:


ViewController.m 

#import "customObj.h" 
-(void)viewDidLoad{ 
    [email protected]"string";//declared in ViewController.h 
} 
-(void)createObj{ 
    [email protected]"different string"; 
    customObj *customObjInstance=[[customObj alloc] init]; 
} 

--- 

customObj.m 

#import "ViewController.h" 
-(void)callBack{ 
    [ViewController createObj]; 
} 

bien, así que cuando se ejecuta de devolución de llamada, él los errores, diciendo que está buscando + createObj (no -createObj). Puedo cambiar createObj a un método de clase, pero luego tiene un problema al configurar foobar porque foobar se inicializó en -viewDidLoad, y no puedo cambiarlo a + viewDidLoad. Tal vez podría mover foobar a un método de clase, pero ¿cómo lo llamo? En lugar de yo, ¿me refiero a [ViewController ...]? No creo que eso funcione

Supongo que me falta un concepto básico y no es tan difícil como lo estoy haciendo. Estoy en deuda con cualquiera que pueda arreglarme.

Muchas gracias.

Respuesta

5

No hay una sola respuesta correcta; depende de cómo su objeto personalizado interactúa con el controlador. La mayoría de las vistas de UIKit utilizan un patrón de "acción de destino" para comunicarse con el controlador, mientras que muchos objetos de modelo usan el patrón de delegado. El que use depende de los detalles de su controlador y su objeto personalizado.

Sin embargo, mecánicamente, lo que probablemente tiene que hacer es pasar un puntero a su ViewController cuando se crea la customObj a través de un inicializador de costumbre, así:

customObj *customObjInstance = [[customObj alloc] initWithController: self]; 

Asegúrese de que tiene sentido para su customObj para estar estrechamente acoplado a su controlador si hace esto.

+0

Hmm ... Gracias. Pasé los indicadores en el pasado, y parece tan complicado que no podía imaginar que era la forma correcta de hacerlo. Entonces, ¿un objeto no tiene referencia al objeto que lo creó? Otros idiomas con los que he trabajado tienen algo así como 'parent', que es distinto de la superclase del objeto. Si tengo un objeto uiview que crea un objeto uitableview, ese objeto tableview no tiene ninguna referencia a la instancia uiview que lo generó? Esa omisión es una a la que siempre me enfrento. Gracias de nuevo. –

+0

Las vistas tienen el concepto de una "supervista", que es la vista en la que están contenidas, pero no existe un concepto general de "creación de objeto". Por lo general, usted decide qué relación tiene el objeto controlador con el objeto modelo. En su caso, por ejemplo, puede decidir que una instancia de CustomObj necesita otro objeto para crear más objetos para él, y puede modelar eso usando un delegado (que es, en el fondo, un puntero a otro objeto, pero es más genérico). Hay todo tipo de formas de hacerlo, y la mejor manera depende de su circunstancia específica. –

+0

Si quieres que un objeto tenga un "padre", le das uno. En general, no encuentro que necesite un acoplamiento específico. – Chuck

3

Puede que me haya lanzado varias menciones de clase a instancia de clase, pero si todo lo que quiere decir es que el controlador necesita crear objetos que puedan llamar al controlador (para crear más de lo mismo), eso puedo ayudarte con

hago esto un poco, usando - como John ha mencionado - el patrón de delegación:

definir un protocolo para las llamadas desde el objeto al controlador: de devolución de llamada

// CallBackDelegate.h 


#import <Foundation/Foundation.h> 

@protocol CallBackDelegate<NSObject> 
- (void)callBack; 
@end 

en el archivo de cabecera para el controlador puedo importar el protocolo

#import "CallBackDelegate.h" 

y especificar que el controlador implementa este protocolo:

@interface MyViewController : UIViewController <CallBackDelegate> 
{ ... 

mientras que en la cabecera de la clase de objeto personalizado también importar el protocolo

#import "CallBackDelegate.h" 

y añadir un miembro de instancia que se ajusta al protocolo:

id<CallBackDelegate> delegate; 

y una propiedad, que debe ser asignar no retener o tendrá retenciones circulares, el controlador y el objeto personalizado se retendrían entre sí, lo que significaría que nunca desasignarían

@property(assign) id<CallBackDelegate> delegate; 

(esta persona no tiene que ser llamado delegado)

A continuación, asegúrese de que cuando el controlador de vista crea el objeto personalizado se pone a sí mismo como el delegado

customObject.delegate = self; 

Luego, en el objeto personalizado que son seguros para hacer esto:

[ delegate callBack]; 

esperanza de que ayuda, estera

si busca el código de ejemplo de Apple, encontrará ejemplos de algo así como:

[delegate toquesEnded: toques withEvent: event];

, por supuesto, si desea que el método para pasar que un id al objeto creado, el método no tiene que devolver (void) como en mi ejemplo

si desea puede escribir un método init que toma al delegado como john también sugirió

customObj * customObjInstance = [[customObj alloc] initWithController: self];

dentro de initWithController el controlador que pase debe ser asignado como delegado

+0

De hecho, la delegación es un patrón muy común que se utiliza en muchos objetivos C, y los protocolos son la clave para que sea fácil hacerlo. –

Cuestiones relacionadas