將app的架構由MVC轉向MVVC,會產(chǎn)生許多的優(yōu)點,個人覺得在一下幾個方面的優(yōu)勢比較突出。
?1.把視圖控制器的業(yè)務邏輯與視圖展示相互隔離,試視圖控制器類專門來管理視圖的展示,業(yè)務邏輯單獨出來在另外一個ViewModel來管理。
2.工程慢慢具體化了以后,項目中的文件會相當?shù)亩唷H绻龅焦δ艿母拢覀兛梢灾苯幼宇惢幌耉iewModel,再到視圖控制器里更新一下ViewModel。如果遇到需要更換視圖,可以將ViewModel重現(xiàn)綁定一下,不會對之前的業(yè)務邏輯產(chǎn)生任何影響。這也是將二則分隔開來,所帶來的好處。
由此可見,花點時間來將工程的架構轉化成MVVC是值得的。
在此,我們將之前的圖片處理的項目進行一下轉換。首先,觀察一下工程下面目錄,有ViewController和AppDelegate,由于沒有涉及到數(shù)據(jù)結構,所以項目中暫時沒有MVC中的數(shù)據(jù)Model,View在ViewController中作為一個成員屬性;AppDelegate是UIApplication的代理,遵守UIApplicationDelegate協(xié)議,在這里可以將它歸為項目中的其它部分。
那么,由MVC轉向MVVC的首要任務也就是將ViewController解耦。這里我們創(chuàng)建一個繼承自NSObject的子類PicViewModel,再給該類創(chuàng)建如下成員屬性:
@property (strong, nonatomic)? UIImageView *imageView;
@property (strong, nonatomic)? UIBarButtonItem *picBtn;
@property (strong, nonatomic)? UISlider *sliderVal;
@property (strong, nonatomic)? UIButton *dealB;
@property (strong, nonatomic)? UIPickerView *picker;
@property (strong, nonatomic)? UIViewController *totalVc;
@property (nonatomic,strong)? RACCommand *picCommand;
其中的視圖空間要與視圖控制器里的視圖空間保持對應關系,RACCommand是第三方庫ReactiveCocoa里面的一個類,用來發(fā)送信號,也是由MVC轉向MVVC的關鍵屬性(關于ReactiveCocoa的詳細介紹,可參考我之前的博客《ReactiveCocoa一些學習摘抄》里面的一些資料)。在成員屬性創(chuàng)建完成之后,我們可以復寫一下初始化方法,把事件進行一下綁定,綁定的代碼如下:
_picCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
? ? ?[self viewWillAppear];
? ? ?RACSignal *sig = [RACSignal createSignal:^RACDisposable *(id subscriber) {
? ? ?return nil;
? ? ?}];
?? ? ? ? ? ? return sig;
}];
在代碼中調(diào)用[self viewWillAppear],就相當于調(diào)用視圖控制器中的-(void)viewWillAppear:(BOOL)animated方法,一些業(yè)務邏輯的關系,我們都可以添加到viewWillAppear方法之下(這是個自定義方法!!)。
完成這一步之后,ViewModel類就創(chuàng)建完成,接下來只需到原來的視圖控制器中將視圖控件與PicViewModel進行一下指向,再在視圖加載方法中調(diào)用一下RACCommand成員的subscribeNext方法即可,具體代碼如下:
self.pictureVM.imageView = self.imageView;
self.pictureVM.picBtn = self.picBtn;
self.pictureVM.sliderVal = self.sliderVal;
self.pictureVM.dealB = self.dealB;
self.pictureVM.picker = self.picker;
self.pictureVM.totalVc = self;
RACSignal *sig = [self.pictureVM.picCommand execute:nil];
[sig subscribeNext:^(id x) {
}];
轉型完成之后,編譯工程運行。如果各個功能和操作與之前一樣,那么轉型成功。
其實由MVC轉向MVVC步驟十分簡單,但是所帶來的益處是巨大的。花費一點點時間將項目改變一下架構,會非常有益于后期的開發(fā),值得學習于借鑒。
最后,該工程的完整代碼請參考我的Github:https://github.com/AirChen/PictureDel
該系列之前的文章請參考:http://blog.sina.com.cn/s/blog_bfb0501f0102vx1v.html