1. 程式人生 > >(iOS-框架封裝)iOS設計模式——MVC模式

(iOS-框架封裝)iOS設計模式——MVC模式

       MVC模式是iOS程式設計中提到的最多次的設計模式,也是使用最頻繁的設計模式之一。網路上有很多的MVC模式的分析文章,但都是從原理上來解釋,很少能找到配套的案例來說明到底在實際的專案中要如何的使用這種模式。小編在經過詳細的研究、對比和實驗了之後,總結了一下這個模式的一些簡單使用方法,希望能起一個拋磚引玉的作用,使得對MVC預設的同學能依葫蘆畫瓢的瞭解MVC模式的使用方法,並以此類推出更多、更好的方法出來。

       這篇文章先從老生常談的MVC設計模式的原理說起,然後配上一個簡單的案例,以演示如何將一個常規的程式設計改為使用MVC模式來程式設計。

       本文假定,您已經熟悉了target-action模式、delegate模式、Notification或KVO模式。如果這幾個模式還不是很瞭解,可參考網路上其它文章說明,本文不會就這些模式做詳細講解。

一、什麼是MVC?

      MVC是model-view-control的簡稱。在解釋這個名詞之前,我們先假定一個案例,在這個例子中,有兩個文字框T1和T2、兩個按鈕B1和B2,B1為儲存按鈕,B2為載入按鈕;T1為文字內容編輯按鈕,當點選B1時,將T1裡面的內容儲存到資料庫中;當點選B2時,將資料庫中儲存的內容顯示到T2上。為了驗證這個操作是否是經過資料庫了,我們可以做一個操作,比如將T1裡面的內容後面加上一些字元、符號等(這個相信很好做吧,你可以在將T1的資料儲存到資料庫的時候做這個操作,也可以在將資料從資料庫中調出、顯示在T2上之前做這個操作,本案例不在詳細敘述)。當我們腦海裡形成好了這樣一個應用之後,下面我們來看看M、V、C到底做什麼樣的工作:

      View——顧名思義,就是存放檢視使用的。對應上面的例子,我們應該把T1、T2、B1和B2放在View上,對吧?

      Model——即模型。模型一般都有很好的可複用性,統一管理一些資料。在上面的例子中,資料庫是不是可以作為一個模型呢?答案是肯定的。所以,我們就把資料庫的所有操作都放在Model裡面執行——包括但不限於資料庫的建立、插入、查詢、更新和刪除(為啥都放一起?地球人都知道。。。)

     Controller——控制器,充當一個CPU的功能,即該應用程式所有的工作都由Controller統一調控。它負責處理View和Model的事件。具體怎麼調控和處理?在下面的MVC原理裡面,我們將詳細講解。

      MVC模式能夠完成各司其職的任務模式,由於降低了各個環節的耦合性,大大優化Controller的程式碼量,當程式除錯時,如果某一個功能沒有按照既定的模式工作,可以很方便的定位到到底是Controller還是View還是Model出了問題,而且還利於程式的可複用性,建議在程式中能多多使用這個模式。

二、MVC的原理

      上面的內容中,已經詳細描述了model、view和controller之間如何各司其職(即該是誰的東西,誰就要保護好,不能讓另外一個越俎代庖的去處理)。MVC模式雖然是iOS程式設計中使用最廣泛的模式,但論起復雜程度,MVC模式可以算是眾多設計模式之首。通常情況下,MVC模式需要綜合使用target-action模式、delegate模式、Notification或KVO模式等。下圖是斯坦福大學的iOS一堂關於iOS介紹的公開課上所使用的示例圖,這張影象也生動的描繪出來了MVC模式的工作原理,接下來的原理講解也是依託於這張影象:

1、 Controller和View之間可以通訊,Controllor通過outlet(輸出口)控制View,View可以通過target-action、delegate或者data source(想想UITableVeiwDatasource)來和Controller通訊;

2、 Controller在接收到View傳過來的互動事件(View就是完成讓人和程式的互動的呀,比如按B1按鈕)之後,經過一些判斷和處理,把需要Model處理的事件遞交給Model處理(比如剛才的例子中的儲存到資料庫),Controller對Model使用的是API;

3、 Model在處理完資料之後,如果有需要,會通過Notification或者KVO的方式告知Controller,事件已經處理完,Controller再經過判斷和處理之後,考慮下一步要怎麼辦(是默默無聞的在後臺操作,還是需要更新View,這得看Controller的“臉色”行事)。這裡的無線天線很有意思,Model只負責傳送通知,具體誰接收這個通知並處理它,Model並不關心,這一點非常重要,是理解Notification模式的關鍵。

4、 Model和View之間不直接通訊!

       按照上面的原理,我們知道了M、V、C之間的各司其職——Model不儲存控制元件,View不做資料庫操作(但這個也不是絕對,如果需要View做一些資料快取工作,還是需要儲存一些臨時資料的),而Controller就充當了兩者之間的協調器。  

       如此,MVC的原理已經理出來一個頭緒了,那麼我們來看一個實際的例子,來驗證如何使用MVC模式。在這個例子中,View通過target-action模式向Controller傳遞訊息,Controller通過API呼叫Model裡面的方法來處理從View那接收到的訊息;Model處理完資料之後,通過Notification模式向Controller傳遞一個訊息,最終Controller通過一個方法(即Notification的接收方法)彈出來一個對話方塊顯示Model已經處理完成。

三、實際案例

1、 不使用MVC模式的案例:

1.1 使用Xcode建立一個Single View Application,命名為MVCsample。

1.2 在ViewController.h裡面,新增如下程式碼:

[objc] view plain copy print?
  1. @property (nonatomicstrongUIButton *saveBtn; //點選該按鈕,儲存資料 
  2. @property (nonatomicstrongUIButton *loadBtn; //點選該按鈕,載入資料
save_snippets.png
@property (nonatomic, strong) UIButton *saveBtn; //點選該按鈕,儲存資料 
@property (nonatomic, strong) UIButton *loadBtn; //點選該按鈕,載入資料


如下圖所示:


1.3 在ViewController.m檔案的- (void)viewDidLoad方法中,新增如下程式碼:

[objc] view plain copy print?
  1. _saveBtn = [UIButton buttonWithType:UIButtonTypeCustom];  
  2. [_saveBtn setFrame:CGRectMake(505015080)];  
  3. [_saveBtn setTitle:@"儲存" forState:UIControlStateNormal];  
  4. [_saveBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];  //預設的頁面背景色是白色,butotn上的文字的預設顏色也是白色,所以在此處將button上的文字顏色設定為黑色,以便顯示
  5. [_saveBtn addTarget:self action:@selector(saveBtnPressed:) forControlEvents:UIControlEventTouchUpInside];  //新增target-action模式
  6. [self.view addSubview:_saveBtn];  
  7. _loadBtn = [UIButton buttonWithType:UIButtonTypeCustom];  
  8. [_loadBtn setFrame:CGRectMake(5016015080)];  
  9. [_loadBtn setTitle:@"載入" forState:UIControlStateNormal];  
  10. [_loadBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];  
  11. [_loadBtn addTarget:self action:@selector(loadBtnPressed:) forControlEvents:UIControlEventTouchUpInside];  //新增target-action模式
  12. [self.view addSubview:_loadBtn];  
save_snippets.png
    _saveBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    
    [_saveBtn setFrame:CGRectMake(50, 50, 150, 80)];
    
    [_saveBtn setTitle:@"儲存" forState:UIControlStateNormal];
    
    [_saveBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];  //預設的頁面背景色是白色,butotn上的文字的預設顏色也是白色,所以在此處將button上的文字顏色設定為黑色,以便顯示
    
    
    [_saveBtn addTarget:self action:@selector(saveBtnPressed:) forControlEvents:UIControlEventTouchUpInside];  //新增target-action模式
    
    [self.view addSubview:_saveBtn];
    
    
    _loadBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    
    [_loadBtn setFrame:CGRectMake(50, 160, 150, 80)];
    
    [_loadBtn setTitle:@"載入" forState:UIControlStateNormal];
    
    [_loadBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    
    [_loadBtn addTarget:self action:@selector(loadBtnPressed:) forControlEvents:UIControlEventTouchUpInside];  //新增target-action模式
    
    [self.view addSubview:_loadBtn];

如下圖所示:


1.4 在上面的一行程式碼中,我們分別為_saveBtn和_loadBtn添加了target-action模式,接下來在ViewController.m檔案中實現這兩個action方法,程式碼如下:

[objc] view plain copy print?
  1. - (void)saveBtnPressed : (UIButton*)sender{  
  2.     NSLog(@"儲存");  
  3.     NSLog(@"當前裝置的型號:%@", [[UIDevice currentDevice]systemVersion]);  
  4.     /* 
  5.     //從iOS 8開始,蘋果建議不使用UIAlertView和UIActionsheet,而是要使用UIAlertController。從iOS 9開始,UIAlertView和UIActionsheet更是已經被禁用,所以在這個案例中,雖然如下的UIAlertView方法還是可以照常執行,但我們還是遵從蘋果的建議,使用新的技術和方法比較妥當 
  6.     UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"恭喜" message:@"儲存成功" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil]; 
  7.     [alert show]; 
  8.      */
  9.     UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"恭喜"
  10.                                                                              message:@"儲存成功"
  11.                                                                       preferredStyle:UIAlertControllerStyleAlert];  
  12.     UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {  
  13.         NSLog(@"點選了取消按鈕");  
  14.     }];  
  15.     UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {  
  16.         NSLog(@"點選了確定按鈕");  
  17.     }];  
  18.     [alertController addAction:cancelAction];  
  19.     [alertController addAction:okAction];  
  20.     [self presentViewController:alertController animated:YES completion:nil];  
  21. }  
  22. - (void)loadBtnPressed : (UIButton*)sender{  
  23.     NSLog(@"載入");  
  24. }  
save_snippets.png
- (void)saveBtnPressed : (UIButton*)sender{
    
    NSLog(@"儲存");
    
    NSLog(@"當前裝置的型號:%@", [[UIDevice currentDevice]systemVersion]);
    
    /*
    //從iOS 8開始,蘋果建議不使用UIAlertView和UIActionsheet,而是要使用UIAlertController。從iOS 9開始,UIAlertView和UIActionsheet更是已經被禁用,所以在這個案例中,雖然如下的UIAlertView方法還是可以照常執行,但我們還是遵從蘋果的建議,使用新的技術和方法比較妥當
    
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"恭喜" message:@"儲存成功" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil];
    
    [alert show];
     
     */
    
    
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"恭喜"
                                                                             message:@"儲存成功"
                                                                      preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
        
        NSLog(@"點選了取消按鈕");
        
    }];
    
    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        
        NSLog(@"點選了確定按鈕");
        
    }];
    
    [alertController addAction:cancelAction];
    [alertController addAction:okAction];
    
    [self presentViewController:alertController animated:YES completion:nil];
    
    
    
}

- (void)loadBtnPressed : (UIButton*)sender{
    
    NSLog(@"載入");
}

程式碼有點長,不再截圖,各位請自行想象~~~

1.5 然後執行該程式,模擬器顯示如下圖:


點選了“儲存按鈕”後,模擬器及Xcode輸出臺顯示如下圖所示:


再點選AlertView上的“取消”或者“確定”按鈕,Xcode輸出臺顯示如下:


以上內容,就是不使用MVC模式的情況下,我們經常做得內容。下面,我們就按照MVC的原理,來將改程式按照MVC的思想重新做一遍。

2. 使用MVC模式的案例:

2.1 使用Xcode建立一個Single View Application,命名為MVCsampleWithMVC;

2.2 新建三個資料夾(Group),分別命名為M、V和C;

2.3 新建一個名為VView的類,繼承自UIView,並將UIView.h和UIView.m檔案拖到V資料夾下;

2.4 新建一個名為MModel的類,繼承自NSObject,並將MModel.h和MModelm檔案拖到M資料夾下;

2.5 將ViewController.h和ViewController.m檔案拖到C資料夾下。做完2.2~2.5的工作之後,Xcode工作組應該顯示如下圖所示:


2.6 按照MVC的思想,V裡面只存放介面顯示的控制元件,在剛才的例子中,就是“儲存”和“載入”這兩個按鈕,於是,我們把有關這兩個按鈕的程式碼都寫到VView.h和VView.m中。

寫好後的VView.h的程式碼如下:

[objc] view plain copy print?
  1. #import <UIKit/UIKit.h>
  2. @interface VView : UIView  
  3. @property (nonatomicstrongUIButton *saveBtn;  //點選該按鈕,儲存資料
  4. @property (nonatomicstrongUIButton *loadBtn;  //點選該按鈕,載入資料
  5. - (void)viewInit;  //新增一個方法,用於初始化控制元件
  6. @end
save_snippets.png
#import <UIKit/UIKit.h>

@interface VView : UIView

@property (nonatomic, strong) UIButton *saveBtn;  //點選該按鈕,儲存資料

@property (nonatomic, strong) UIButton *loadBtn;  //點選該按鈕,載入資料

- (void)viewInit;  //新增一個方法,用於初始化控制元件

@end

寫好後的VView.m的程式碼如下: [objc] view plain copy print?
  1. #import "VView.h"
  2. @implementation VView  
  3. - (void)viewInit {  
  4.     _saveBtn = [UIButton buttonWithType:UIButtonTypeCustom];  
  5.     [_saveBtn setFrame:CGRectMake(505015080)];  
  6.     [_saveBtn setTitle:@"儲存" forState:UIControlStateNormal];  
  7.     [_saveBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];  //預設的頁面背景色是白色,butotn上的文字的預設顏色也是白色,所以在此處將button上的文字顏色設定為黑色,以便顯示
  8.     [self addSubview:_saveBtn];  
  9.     _loadBtn = [UIButton buttonWithType:UIButtonTypeCustom];  
  10.     [_loadBtn setFrame:CGRectMake(5016015080)];  
  11.     [_loadBtn setTitle:@"載入" forState:UIControlStateNormal];  
  12.     [_loadBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];  
  13.     [self addSubview:_loadBtn];  
  14. }  
  15. @end
save_snippets.png
#import "VView.h"

@implementation VView

- (void)viewInit {
    
    _saveBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    
    [_saveBtn setFrame:CGRectMake(50, 50, 150, 80)];
    
    [_saveBtn setTitle:@"儲存" forState:UIControlStateNormal];
    
    [_saveBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];  //預設的頁面背景色是白色,butotn上的文字的預設顏色也是白色,所以在此處將button上的文字顏色設定為黑色,以便顯示
    
    [self addSubview:_saveBtn];
    
    
    _loadBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    
    [_loadBtn setFrame:CGRectMake(50, 160, 150, 80)];
    
    [_loadBtn setTitle:@"載入" forState:UIControlStateNormal];
    
    [_loadBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    
    [self addSubview:_loadBtn];
    
}

@end

和上面的不使用MVC模式例子相比較,發現_saveBtn和_loadBtn都沒有新增target-action方法。這是因為target-action方法需要設定一個target物件,在這個物件裡呼叫action方法。按照MVC的思想,V裡面不進行資料處理,而是要在C裡面統一調控有C還是M來處理資料。本例中,我們是在C裡面處理,所以我會把targe-action方法寫到C裡面,詳細後面介紹。

2.7 按照MVC的思想,M主要用於資料的處理,我們假設這個案例是要將V中的某一段內容儲存到資料庫中,那麼這個儲存到資料庫中的操作就是在M裡面完成的。此處我們直接簡化操作,只是寫兩個方法,用來提示儲存和載入成功的。如此,MModel.h中的程式碼如下:

[objc] view plain copy print?
  1. #import <Foundation/Foundation.h>
  2. @interface MModel : NSObject  
  3. - (void)save;  
  4. - (void)load;  
  5. @end
save_snippets.png
#import <Foundation/Foundation.h>

@interface MModel : NSObject

- (void)save;

- (void)load;

@end

MModel.m中的程式碼如下: [objc] view plain copy print?
  1. #import "MModel.h"
  2. @implementation MModel  
  3. - (void)save{  
  4.     NSLog(@"儲存。。。");  
  5.     [[NSNotificationCenter defaultCenter] postNotificationName:@"saveSucessful" object:self];  //使用Notification模式傳送一個通知,用於通知Controller要做什麼事情
  6. }  
  7. - (void)load{  
  8.     NSLog(@"載入。。。");  
  9. }  
  10. @end
save_snippets.png
#import "MModel.h"

@implementation MModel

- (void)save{
    
    NSLog(@"儲存。。。");
    
    [[NSNotificationCenter defaultCenter] postNotificationName:@"saveSucessful" object:self];  //使用Notification模式傳送一個通知,用於通知Controller要做什麼事情
    
}

- (void)load{
    
    NSLog(@"載入。。。");
    
}

@end

可以看到,這段程式碼和不使用MVC模式的程式碼中的target-action方法中的action方法是基本上一樣的。那麼我麼就會有一個思路——在Controller中,當我們為按鈕添加了target-action模式之後,對應要實現的action方法裡面,是不是隻需要呼叫MModel.h裡面的對應的- (void)save和- (void)load方法就行了呢?完全正確!看,這就是C通過API呼叫M!

在- (void)save方法中,我還使用Notification模式傳送了一個通知,這個通知用來告知Controller,我已經儲存好資料了,接下來你看著辦!在上一個不使用MVC模式的例子中,Controller是彈出來一個Alert,本例子中,我們也要實現這個功能。

2.8 V和M都已經分配好了,接下來就是看C如何協調分配了。ViewController.h中的程式碼如下:

[objc] view plain copy print?
  1. #import <UIKit/UIKit.h>
  2. #import "VView.h"
  3. #import "MModel.h"
  4. @interface ViewController : UIViewController  
  5. @property (nonatomicstrongVView *aView;  //例項化一個VView的物件
  6. @property (nonatomicstrongMModel *mModel;  //例項化一個MModel的物件,以便於呼叫MModel中的方法
  7. @end
save_snippets.png
#import <UIKit/UIKit.h>

#import "VView.h"

#import "MModel.h"

@interface ViewController : UIViewController


@property (nonatomic, strong) VView *aView;  //例項化一個VView的物件

@property (nonatomic, strong) MModel *mModel;  //例項化一個MModel的物件,以便於呼叫MModel中的方法


@end

由於我在MModel.h中定義的方法都是例項方法,所以我們只能例項化一個MModel的物件來呼叫這些方法。如果將MModel中的方法設定為類方法或者單例模式,就可以直接用MModel這個類來呼叫了。

2.9 ViewContro.m中的程式碼如下:

[objc] view plain copy print?
  1. #import "ViewController.h"
  2. #define deviceScreenWidth [[UIScreen mainScreen]bounds].size.width
  3. #define deviceScreenHeight [[UIScreen mainScreen]bounds].size.height
  4. @interface ViewController ()  
  5. @end
  6. @implementation ViewController  
  7. - (void)viewDidLoad {  
  8.     [super viewDidLoad];  
  9.     [[NSNotificationCenter defaultCenter] addObserver:self
  10.                                              selector:@selector(saveOK:)  
  11.                                                  name:@"saveSucessful" object:nil];  //新增一個通知方法,當這個Controller接收到一個名稱為@"saveSucessful"的通知後,就執行saveOK:方法
  12.     _aView = [[VView alloc]initWithFrame:CGRectMake(00, deviceScreenWidth, deviceScreenHeight)];  //初始化時一定要設定frame,否則VView上的兩個按鈕將無法被點選
  13.     [_aView viewInit];  
  14.     [_aView.saveBtn addTarget:self action:@selector(saveBtnPressed:) forControlEvents:UIControlEventTouchUpInside];  //為“儲存”按鈕新增target-action模式
  15.     [_aView.loadBtn addTarget:self action:@selector(loadBtnPressed:) forControlEvents:UIControlEventTouchUpInside];  //為“載入”按鈕新增target-action模式
  16.     [self.view addSubview:_aView];  
  17.     _mModel = [[MModel alloc]init];  
  18. }  
  19. - (void)saveBtnPressed : (UIButton*)sender{  
  20.     [_mModel save];  //呼叫MModel.h中的方法(API)
  21. }  
  22. - (void)loadBtnPressed : (UIButton*)sender{  
  23.     [_mModel load];  //呼叫MModel.h中的方法(API)
  24. }  
  25. - (void)saveOK : (NSNotification*) notification{  
  26.     UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"恭喜"
  27.                                                                              message:@"儲存成功"
  28.                                                                       preferredStyle:UIAlertControllerStyleAlert];  
  29.     UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {  
  30.         NSLog(@"點選了取消按鈕");  
  31.     }];  
  32.     UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {  
  33.         NSLog(@"點選了確定按鈕");  
  34.     }];  
  35.     [alertController addAction:cancelAction];  
  36.     [alertController addAction:okAction];  
  37.     [self presentViewController:alertController animated:YES completion:nil];  
  38. }  
  39. - (void)didReceiveMemoryWarning {  
  40.     [super didReceiveMemoryWarning];  
  41.     // Dispose of any resources that can be recreated.
  42. }  
  43. @end
save_snippets.png
#import "ViewController.h"

#define deviceScreenWidth [[UIScreen mainScreen]bounds].size.width

#define deviceScreenHeight [[UIScreen mainScreen]bounds].size.height

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(saveOK:)
                                                 name:@"saveSucessful" object:nil];  //新增一個通知方法,當這個Controller接收到一個名稱為@"saveSucessful"的通知後,就執行saveOK:方法
    
    
    _aView = [[VView alloc]initWithFrame:CGRectMake(0, 0, deviceScreenWidth, deviceScreenHeight)];  //初始化時一定要設定frame,否則VView上的兩個按鈕將無法被點選
    
    [_aView viewInit];
    
    [_aView.saveBtn addTarget:self action:@selector(saveBtnPressed:) forControlEvents:UIControlEventTouchUpInside];  //為“儲存”按鈕新增target-action模式
    
    [_aView.loadBtn addTarget:self action:@selector(loadBtnPressed:) forControlEvents:UIControlEventTouchUpInside];  //為“載入”按鈕新增target-action模式
    
    [self.view addSubview:_aView];
    
    _mModel = [[MModel alloc]init];
    
    
}


- (void)saveBtnPressed : (UIButton*)sender{
    
    [_mModel save];  //呼叫MModel.h中的方法(API)
}

- (void)loadBtnPressed : (UIButton*)sender{
    
    [_mModel load];  //呼叫MModel.h中的方法(API)
}


- (void)saveOK : (NSNotification*) notification{
    
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"恭喜"
                                                                             message:@"儲存成功"
                                                                      preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
        
        NSLog(@"點選了取消按鈕");
        
    }];
    
    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        
        NSLog(@"點選了確定按鈕");
        
    }];
    
    [alertController addAction:cancelAction];
    [alertController addAction:okAction];
    
    [self presentViewController:alertController animated:YES completion:nil];
    
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

程式碼裡面有一些注意事項,我都用註釋的形式寫在了程式碼的後面,請讀者自行研究判斷,此處不再贅述,有疑問歡迎留言討論。從C的程式碼中可以看到,如何在MVC中使用target-action模式(delegate模式和data source模式,暫時不在這個案例中講述),如何在C中呼叫M中的API,以及M如何通過Notification模式向C傳送通知並由C處理相關的通知。雖然M+V+C裡面的程式碼總量比不使用MVC模式多了一些,但MVC模式寫出來的程式碼層次分明,結構清楚,分工明確,為以後修改程式碼、除錯程式都帶來了極大的便利。比如你要修改顯示的效果,只需要修改V中的就行,然後按照調理在C中新增相應的方法,多麼明確。使用MVC模式的執行效果我就不再附圖了,親測程式能正常工作,請讀者自己也試一試吧,手動寫寫程式碼,對理解程式碼會有很大的幫助的。

四、結語

       至此,MVC模式的介紹就算結束了。可能很多讀者對這麼一個小程式就使用MVC模式覺得有點得不償失,但萬丈高樓平地起,只有從小處開始就能注意細節方面的事情,對以後寫大型程式來講,會非常的有幫助的。在程式設計界,一直流傳有一個觀點——一週不寫程式碼,再寫時就會覺得手生。其實,很多程式碼或者程式設計習慣,並不是靠腦袋記住的,而是靠習慣養成的。只有習慣了使用良好的設計模式,才能對設計模式的使用“聊熟於胸”,才能“信手拈來”。我也相信,MVC模式絕對不止這麼一點點的思想和方法,希望有興趣的讀者朋友,能多多深入研究,多多與人探討,將MVC的模式深挖掘,挖出它的靈魂。

       本文如有紕漏,歡迎各位同仁指出並給出修改建議,為後來者提供更加準確的諮詢。

——————————————————————————————————

歡迎關注我的微博:http://weibo.com/u/5750370715/home?wvr=5&c=spr_web_360_hao360_weibo_t001

歡迎關注我的微信公眾號,您的支援,我的榮幸。微信搜尋“登頂望峰”或者掃描如下影象二維碼即可關注。我將會在公眾號中不定時推送開發相關的技巧、諮詢、業界新聞等。