2012-08-02 26 views
5

我是兼職記事本網站編碼器,正在採取措施進入IOS應用程序。上週我得到了第一個mac,並且拼湊了一個半工作的應用程序。現在,通過這個SO answer確信,我正在重新嘗試學習MVC。我的學習曲線非常陡峭,請耐心等待。Xcode - 這是MVC嗎?

我已經在MVC,在層分離,三個箱和一些箭頭讀了,我明白了。然而,將理論轉化爲現實世界令人沮喪。我看過的大多數示例應用程序似乎都沒有使用MVC。即使這個來自蘋果的LazyTableImages example似乎使用app delegate作爲混淆我的模型。我很好地建立了這個simple MVC example

我的應用程序從Web服務檢索位置標記。我有一個使用ARC的選項卡式應用程序。一個選項卡具有Mapkit地圖來顯示標記。

一個簡單的類,它保持一個標記記錄:

@interface MarkerRecord : NSObject 

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

一個模型類,控股標記類的集合,同時服務的意見。這是我的模型類的.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實現(的開始)?

如果是這樣的:

  • 我怎麼模型更新控制器(即我怎麼MarkersModel.objectLoader函數調用mapViewController.putMarkersOnMap)?

我強烈懷疑答案是控制器上的自定義委託,但我不能爲我的生活看到如何實現它。我無法將任何例子與我的情況聯繫起來。我想我需要像這樣的控制器上:

@class MapViewController; 
@protocol MapViewControllerDelegate; 

雖然我在它的一些其他問題:

  • 我將創建任何懸擺指針 - 我懷疑的東西應該是unsafe_unretained(我編譯到4.3)?
  • 是在控制類我MarkersModel聲明是否正確?我擔心它不會由ARC管理。我也懷疑它是公開的,但應該是私人的。
  • 如若MarkersModel.getMarkers方法是靜態的?

我希望這是明確的和可接受的問題。感謝您的耐心,波莉。

回答

5

是我的代碼大綱上面(開始)體面的MVC實現嗎?

以我的標準,是

我怎麼模型更新

你是正確的,你要使用委託控制器。您聲明委託協議以及它代表的類。所以,在你的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]; 
    } 
} 

我將創建任何懸擺指針 - 我懷疑有些東西應該是unsafe_unretained(我正在編譯爲4.3)?

這並不是說我知道

是在控制類我MarkersModel聲明是否正確?我擔心它不會由ARC管理。我也懷疑它是公開的,但應該是私人的。

您可以通過預先添加@private頭將它聲明爲private:

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

如若MarkersModel.getMarkers方法是靜態的?

如果是靜態的,你的意思是作爲一個類而不是實例級的方法,這完全取決於你的實現。如果所有的MarkersModel對象都應該保留相同的數據,那麼是的,它是有道理的,使其級別級別。但是,如果每個MarkersModel對象應該保持它自己的一套Markers然後不,應該保持一個實例級別的方法

+1

這是很好的;代表的使用非常普遍。如果您有多個控制器有興趣改變模型的任何可能性,您可能想要評估的另一種方法是「關鍵值觀察」。 http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html – 2012-08-02 20:47:06

+0

@PhillipMills有用的鏈接,我其實是最近纔得到真正下到如何提高基本事實我的MVC編程,這應該真的幫助我出來 – 2012-08-02 20:49:46

+0

偉大的信息。非常感謝。 – Polly 2012-08-03 06:24:46