一、什么是MVC
單例、通知等是我們在項目中經常用到設計代碼的一種方式,MVC和他們一樣也是一種用來設計代碼的模式,他就像一個模板,一個框架,我們這個以這個框架為模子,創造我們的代碼。
二、MVC的分工
M(Model)
1、給ViewController存儲數據、處理數據、提供數據
一般的我們在Model會有很多屬性,這些屬性就是用來保存數據的;
我們在Controller里面拿到這些屬性就可以給View賦值,這就是Model給Controller提供數據,Controller將數據給View;
有時候Model中存儲數據的時候需要對數據進行處理,比如數據需要轉換成字符串存在屬性里等,這都是在Model中做完,然后存儲起來,這就是處理數據。
2、給ViewController提供接口
有很多小伙伴將Api接口直接寫在Controller里面,拿到服務器請求到的數據后直接在Controller里面處理,處理完直接用,這樣可以實現功能,但是請求多了、項目大了導致Controller里面各種代碼,各種邏輯,慢慢就難以維護了。這樣做其實是將Model的工作交給了Controller,Model的職能沒有被做大的化的使用。
其實我們可以將Api寫在Model里面,Model請求到服務器數據的時候在Model做完數據處理,然后直接返回給Controller,Controller拿到Model處理好的數據直接做其他刷新UI的操作這不是很有章法的嗎,而且邏輯緊湊,分工明確。
3、提供經過抽象業務基本組件,供Controller調度
- 舉個很簡單的例子,大家項目里有沒有用攝像頭,或者定位等功能,我們把這些功能進行二次封裝,封裝成我們項目所需要的,更能給項目提供更加便捷的類。這些類我們大多數人把它叫做Manager,定位管理類,系統相冊管理類...這些繼承于NSObject的類被你改了個名字你就不知道它屬于Model的嗎?他們其實是一回事,都是Model,有些人可能會說照你這樣說只要是繼承NSObjct的類都是Model,我可以確切的告訴你:是的,沒毛病。
V(View)
1、構成UI
- 注意點就不用說了,View上面有各種UI界面的東西。
2、響應UI事件
這里注意了,相應UI事件不是說相應事件的處理就在View中做,如果你這樣做你可以試試看;
View的事件通過代理的形式告知Controller,Controller實現協議執行事件的代理,這時候在代理里面處理業務操作;
強調一點就是關于一些UI的動畫,如果合適的話盡量放在View里面去做;
3、展示UI
- 也不用說,UI需要填充數據,展示UI。
C(Controller)
1、管理ViewController的生命周期
- Controller的周期函數
2、負責初始化所有UI的實例,并將其添加到self.view上
- 在Controller中將創建View并添加在self.view上,使得UI展示出來。
3、通過監聽、代理等方式處理來自View與業務先關的事件,實現相關業務
- 在Controller實現View的代理或者監聽,當View層有事件發生的時候就會委托Controller實現代理方法,在代理方法中處理好相關的業務。
4、通過與Model的交互,獲取Model的數據,將數據給View
- Controller中通過Model發起網絡請求,然后Model將網絡請求來的數據處理好后返回給Controller,Controller在將這些數據給View,實現給View界面賦值或者刷新View數據。
三、 MVC的本質
1、Model就是一個繼承自NSObject的類;
- 在MVC設計模式中,大多數人將Model看做是Controller的Model,其實它不僅僅可以作為Controller的Model,它也可以看做是view的Model,哪個view呢,就是Controller自帶的self.view。在MVVM中View有自己的Model,在這里是同理。當然你可以在項目中將Controller的Model和View的Model分開,各自管理各自的Model,View的Model為View提供數據,Controller的Model為Controller提供api接口,視項目情況定,不深入學習和體會對view的Model和Controller的Model界限會很模糊。
2、View就不用說了;
3、重點來說一下Controller
Controller的組成:Controller大家都知道它是容器,那它為什么可以作為容器?
首先來看Controller的組成,從新建的Controller里面我們可以看出來Controller是由周期函數、一個View,即self.view組成,或者還有其他的,就不說了不是重點。
也就是說Controller上面是有一個View的,那為什么需要這個View呢,因為我們將創建的UI實例都放在這個View上,才能將UI展示出來。
這樣一來就透徹了,Controller上有個View,我們將UI是放在這個View上才能展示出來的,Controller里面裝了一些UI,與其說是Controller裝了些UI還不如說,因為Controller上面有一個View,這個View里面裝了一些UI的實例,所以才能展示出來UI層。
所以說View才是個容器,Controller如果沒有自帶的這個View它就不能被稱作是容器。
所以說在iOS里面UIView不光可以用作是展示UI的對象,還可以作為容器的一個對象。
四、示例
這里有一個ViewController,ViewController里面有一個View,_userInfoView用來展示用戶信息。ViewController中還有一個UserInfoModel用來存儲和管理用戶信息。
@interface ViewController ()
{
UserInfoView *_userInfoView;
}
/**
ViewController的Model
*/
@property (nonatomic, strong) UserInfoModel *infoModel;
@end
ViewController中周期函數:
#pragma mark cycle
- (void)viewDidLoad {
[super viewDidLoad];
//UI
[self setUpUI];
//request
[self requestUserInfo];
}
這里沒寫其他周期函數,看項目需要自行添加。在viewDidLoad里面一個方法是初始化UI,另一個方法請求服務端數據。
infoModel通過懶加載用的時候在創建。
在請求數據的方法中需要做很多處理和操作:
#pragma mark request
- (void)requestUserInfo {
//Code...
/*1、在這里通過self.infoModel調起一個方法;
2、通過此方法在self.infoModel中發起請求用戶數據的網絡請求;
3、請求返回后在self.infoModel中處理好數據,將數據保存在UserInfoModel中;
4、然后將結果用block或者代理的方式回調到ViewController中;
5、ViewController得到回調后,從self.infoModel拿到數據,然后賦值給_userInfoView;
6、_userInfoView通過賦值的方法將用戶信息賦值在view上展示出來。
*/
}