2012-08-02 9 views
5

Soy un codificador de sitio web de bloc de notas de medio tiempo que da pasos en las aplicaciones IOS. Recibí mi primer mac la semana pasada y he improvisado una aplicación que funciona a medias. Ahora, convencido por este SO answer, estoy reiniciando intentando aprender MVC. Estoy en una curva de aprendizaje muy empinada así que por favor tengan paciencia conmigo.Xcode - ¿Es este MVC?

He leído en MVC, separación de capas, tres cajas y algunas flechas, lo entiendo. Sin embargo, traducir la teoría al mundo real es frustrante. La mayoría de las aplicaciones de ejemplo que he visto no parecen usar MVC. Incluso este LazyTableImages example de Apple parece usar app delegate como el modelo que me confunde. He construido sobre esto excelentemente simple MVC example.

Mi aplicación recupera marcadores de ubicación de un servicio web. Tengo una aplicación con pestañas usando ARC. Una pestaña tiene un mapa de Mapkit para mostrar los marcadores.

una clase simple para sujetar un disco marcador:

@interface MarkerRecord : NSObject 

@property (strong, nonatomic) NSDecimalNumber *lat; 
@property (strong, nonatomic) NSDecimalNumber *lon; 
@property (strong, nonatomic) NSString *des; 

una clase del modelo, con una colección de clases de marcadores, para servir a ambos puntos de vista. Esta es mi clase .h Modelo:

@interface MarkersModel : NSObject 

- (void)getMarkers; // Send HTTP GET to web service to retrieve JSON markers 
- (void)postMarker; // Send HTTP POST to web service to INSERT new marker record 

Y la aplicación:

@interface MarkersModel() 
@property (strong, nonatomic) NSArray *data; 
@end 

@implementation MarkersModel 
@synthesize data; 

- (void)getMarkers 
{ 
    // Send HTTP GET to web service to retrieve JSON markers 
    ... 
} 

- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects 
{ 
    // Thanks to Restkit data is an array of Marker classes 
    data = objects; 

    // Pass data to controller 

} 

Un .h clase mapViewController:

#import <MapKit/MapKit.h> 
#import "MarkersModel.h" 

@interface MapViewController : UIViewController<MKMapViewDelegate> { 
    MarkersModel *markersModel; 
} 

@property (nonatomic, strong) IBOutlet MKMapView *mapView; 

@end 

Y la aplicación:

@interface MapViewController() 
@end 

@implementation MapViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Create instance of markers model 
    markersModel = [[MarkersModel alloc] init]; 
} 

-(void)viewWillAppear:(BOOL)animated 
{ 
    [markersModel getMarkers]; 
} 

- (void)putMarkersOnMap 
{ 
    // To be called by Markers Model 
    ... 
} 

Aquí está mi pregunta principal:

  • ¿Mi esquema de arriba es (el comienzo de) una implementación decente de MVC?

Si es así:

  • ¿Cómo consigo el modelo para actualizar el controlador (es decir, ¿cómo puedo obtener la función MarkersModel.objectLoader para llamar mapViewController.putMarkersOnMap)?

Sospecho que la respuesta es un delegado personalizado en el controlador pero no puedo ver cómo implementarlo. No puedo relatar ningún ejemplo a mi situación. Creo que necesito algo como esto en el controlador:

@class MapViewController; 
@protocol MapViewControllerDelegate; 

Mientras estoy en ello algunas preguntas adicionales:

  • Voy a crear ninguna referencia colgante - Sospecho que algo debe ser unsafe_unretained (Estoy compilando a 4.3)?
  • ¿Es correcta la declaración de mi MarkersModel en la clase de controlador? Me preocupa que no sea administrado por ARC. También sospecho que es público, pero debe ser privado.
  • ¿El método MarkersModel.getMarkers debe ser estático?

Espero que esto sea claro y una pregunta aceptable.Gracias por tu paciencia, Polly.

Respuesta

5

¿Está mi esquema de código arriba (el comienzo de) una implementación MVC decente?

para mis estándares, sí

¿Cómo consigo el Modelo para la actualización del controlador

Estás en lo correcto, que desea utilizar un delegado. Usted declara el protocolo de delegado junto con la clase para la que es delegado. Así que la expansión en su cabecera MarkersModel:

@protocol MarkersModelDelegate<NSObject> 
-(void) markersDidUpdate:(MarkersModel*)model; 
@end 

@interface MarkersModel : NSObject 
{ 
    __weak id<MarkersModelDelegate> delegate; 
} 

@property(weak,nonatomic) id<MarkersModelDelegate> delegate; 

Luego, en el controlador de vista:

@interface MapViewController : UIViewController<MKMapViewDelegate, MarkersModelDelegate> { 

Luego, en la implementación del modelo:

@implementation MarkersModel 

@synthesize delegate; 

//... 

-(void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects 
{ 
    // Thanks to Restkit data is an array of Marker classes 
    data = objects; 

    // Pass data to controller 
    if(delegate != nil) 
    { 
     [delegate markersDidUpdate:self]; 
    } 
} 

Voy a crear ninguna referencia colgante - I sospecho que algo debe ser inseguro_unretenido (estoy compilando a 4.3)?

No es que yo soy consciente de

Es mi declaración MarkersModel en la clase del controlador correcto? Me preocupa que no sea administrado por ARC. También sospecho que es público, pero debe ser privado.

se puede declarar como privada mediante la adición de la cabecera @private antemano:

@interface MapViewController... 
{ 
@private 
MarkersModel *markersModel; 
... 

caso de que el método MarkersModel.getMarkers ser estático?

Si por estático, quiere decir como un método de nivel de clase en lugar de a nivel de instancia, eso depende completamente de su implementación. Si se supone que todos los objetos MarkersModel conservan los mismos datos, entonces sí tiene sentido hacerlo a nivel de clase. Pero si se supone que cada objeto MarkersModel conserva su propio conjunto de Markers, entonces no, debe seguir siendo un método de nivel de instancia

+1

Esto es bueno; el uso de delegados es muy común. Una alternativa que quizás desee evaluar también es "Observación de valores clave" si tiene alguna posibilidad de que más de un controlador esté interesado en cambios en el modelo. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html –

+0

@PhillipMills Enlace útil, en realidad recientemente me he metido de verdad en el meollo de cómo mejorar mi programación de MVC, esto realmente debería ayudarme –

+0

Excelente información. Muchas gracias. – Polly