我已经读过MVC,分层,三个盒子和一些箭头,我明白了.然而,将理论转化为现实世界令人沮丧.我看过的大多数示例应用程序似乎都没有使用MVC.即使是来自Apple的LazyTableImages example似乎也使用app delegate作为让我困惑的模型.我很好地建立了这个simple MVC example.
我的应用从网络服务中检索位置标记.我有一个使用ARC的标签应用程序.一个选项卡有一个Mapkit地图来显示标记.
一个简单的类来保存标记记录:
@interface MarkerRecord : NSObject @property (strong,nonatomic) NSDecimalNumber *lat; @property (strong,nonatomic) NSDecimalNumber *lon; @property (strong,nonatomic) NSString *des;
一个Model类,包含一组Marker类,用于提供两个视图.这是我的Model类.h:
@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
并实施:
@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 }
一个mapViewController类.h:
#import <MapKit/MapKit.h> #import "MarkersModel.h" @interface MapViewController : UIViewController<MKMapViewDelegate> { MarkersModel *markersModel; } @property (nonatomic,strong) IBOutlet MKMapView *mapView; @end
并实施:
@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 ... }
这是我的主要问题:
>我的代码是否是一个体面的MVC实现的上面(开头)?
如果是这样:
>如何让Model更新Controller(即如何让MarkersModel.objectLoader函数调用mapViewController.putMarkersOnMap)?
我强烈怀疑答案是控制器上的自定义委托,但我不能为我的生活看到如何实现它.我无法将任何例子与我的情况联系起来.我想在控制器上我需要这样的东西:
@class MapViewController; @protocol MapViewControllerDelegate;
虽然我还有其他一些问题:
>我会创建任何悬空指针 – 我怀疑某些事情应该是不安全的(我编译为4.3)?
>我在控制器类中的MarkersModel声明是否正确?我担心它不会由ARC管理.我也怀疑它是公开的,但应该是私人的.
> MarkersModel.getMarkers方法应该是静态的吗?
我希望这是明确的,也是一个可接受的问题.感谢你的耐心,波莉.
解决方法
Is my code outline above (the beginnings of) a decent MVC implementation?
按我的标准,是的
how do I get the Model to update the Controller
你是对的,你想使用委托.您声明委托协议以及它作为委托的类.所以扩展你的MarkersModel标题:
@protocol MarkersModelDelegate<NSObject> -(void) markersDidUpdate:(MarkersModel*)model; @end @interface MarkersModel : NSObject { __weak id<MarkersModelDelegate> delegate; } @property(weak,nonatomic) id<MarkersModelDelegate> delegate;
然后在你的视图控制器中:
@interface MapViewController : UIViewController<MKMapViewDelegate,MarkersModelDelegate> {
然后在模型实现中:
@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]; } }
Will I create any dangling pointers – I suspect something should be unsafe_unretained (I am compiling to 4.3)?
不是我知道的
Is my MarkersModel declaration in the controller class correct? I am concerned that it will not be managed by ARC. I also suspect it is public but should be private.
您可以通过事先添加@private标头将其声明为私有:
@interface MapViewController... { @private MarkersModel *markersModel; ...
Should the MarkersModel.getMarkers method be static?
如果使用static,则表示作为类级别而非实例级别方法,这完全取决于您的实现.如果所有MarkersModel对象都应该保留相同的数据,那么将它设置为类级别是有意义的.但是如果每个MarkersModel对象都应该保留自己的标记集,那么它应该保留为实例级方法