接上一篇文章
說到使用ViewModel
來瘦身ViewController
,也就是把ViewController
中有關(guān)原始數(shù)據(jù)適配到view
需要的數(shù)據(jù)的一種辦法.
- (void)onRoomInfoUpdateNotification:(NSNotification*)notification
{
MFChatRoomMessage* message = [[MFChatRoomMessage alloc] init];
message.msgType = kSystemType;
message.msgSubType = kPlanTextSubType;
MFRoomInfo* roomInfo = [[MFAppModel sharedObject].chatroomModelEx getCurrentRoomInfo];
NSNumber* isLock = [[notification userInfo] objectForKey:KChatRoomIsLockChangeKey];
NSNumber* isTopicChange = [[notification userInfo] objectForKey:KChatRoomIsTopicChangeKey];
if (isLock.unsignedIntegerValue == 1) {
message.msgText = (roomInfo.locked ? @"房主將房間鎖定" : @"房主將房間解鎖了");
} else if (isTopicChange.unsignedIntegerValue == 1) {
message.msgText = [NSString stringWithFormat:@"房主更改了話題 %@", roomInfo.subject];
} else {
message.msgText = @"房主更改了房間信息";
}
[self appendChatRoomMessage:message forceRefresh:YES];
}
截取上面一段代碼僅供參考說明,這段代碼實際上就干了一件事:
[self appendChatRoomMessage:message forceRefresh:YES];
把message
傳給appendChatRoomMessage
進行后續(xù)的處理,而上面的若干行代碼都是對message
進行賦值,那最簡單的想法就是能否通過一個方法可以直接獲取到message
,有了這樣的想法,我們會定義這樣的方法
+ (MFChatRoomMessage *)getChatRoomMessage:(NSNotification*)notification msgType:(MFChatRoomMsgType)msgType msgSubType:(MFChatRoomMsgSubType)msgSubType {
MFChatRoomMessage* message = [[MFChatRoomMessage alloc] init];
message.msgType = kSystemType;
message.msgSubType = kPlanTextSubType;
MFRoomInfo* roomInfo = [[MFAppModel sharedObject].chatroomModelEx getCurrentRoomInfo];
NSNumber* isLock = [[notification userInfo] objectForKey:KChatRoomIsLockChangeKey];
NSNumber* isTopicChange = [[notification userInfo] objectForKey:KChatRoomIsTopicChangeKey];
if (isLock.unsignedIntegerValue == 1) {
message.msgText = (roomInfo.locked ? @"房主將房間鎖定" : @"房主將房間解鎖了");
} else if (isTopicChange.unsignedIntegerValue == 1) {
message.msgText = [NSString stringWithFormat:@"房主更改了話題 %@", roomInfo.subject];
} else {
message.msgText = @"房主更改了房間信息";
}
return message;
}
那接下來ViewController
里面只需要寫
- (void)onRoomInfoUpdateNotification:(NSNotification*)notification
{
MFChatRoomMessage* message = [MyViewModel getChatRoomMessage:notification msgType:kSystemType msgSubType:kPlanTextSubType];
[self appendChatRoomMessage:message forceRefresh:YES];
}
這樣就只要在VC
里寫兩句話,而構(gòu)造message
的細節(jié)都封裝在ViewModel
里.
我們可能有很多像onRoomInfoUpdateNotification
這樣的回調(diào),最終都要轉(zhuǎn)換成MFChatRoomMessage
, 那既然這類notification
的作用只是對數(shù)據(jù)進行處理,和UI并沒半毛錢關(guān)系,那就可以直接把這些全都封裝到ViewModel
里.接下來再看下我們的appendChatRoomMessage
里面到底要干什么
- (void)appendChatRoomMessage:(MFChatRoomMessage *)message forceRefresh:(BOOL)forceRefresh
{
[_msgArray addObject:message];
if (_msgArray.count > 50) {
[_msgArray removeObjectAtIndex:0];
}
if (forceRefresh) {
[self reloadAllMessage];
return;
}
}
把數(shù)據(jù)message
加到一個數(shù)組,然后刷新UI,所以我們最終的目的還是刷UI,那實際上我們的ViewController
連msgArray
都不需要了,只要持有ViewModel
就可以了
所以綜上所述,MyViewModel
應(yīng)該是類似這樣的
@interface MyViewModel : NSObject
@property (nonatomic, strong) NSMutableArray *msgArray;
- (void)addChatRoomMessage:(NSNotification*)notification msgType:(MFChatRoomMsgType)msgType msgSubType:(MFChatRoomMsgSubType)msgSubType;
@end
@implementation
- (NSMutableArray *)msgArray {
if(_msgArray == nil) {
_msgArray = [NSMutableArray array];
}
return _msgArray;
}
- (MFChatRoomMessage *)getChatRoomMessage:(NSNotification*)notification msgType:(MFChatRoomMsgType)msgType msgSubType:(MFChatRoomMsgSubType)msgSubType {
MFChatRoomMessage* message = [[MFChatRoomMessage alloc] init];
message.msgType = kSystemType;
message.msgSubType = kPlanTextSubType;
MFRoomInfo* roomInfo = [[MFAppModel sharedObject].chatroomModelEx getCurrentRoomInfo];
NSNumber* isLock = [[notification userInfo] objectForKey:KChatRoomIsLockChangeKey];
NSNumber* isTopicChange = [[notification userInfo] objectForKey:KChatRoomIsTopicChangeKey];
if (isLock.unsignedIntegerValue == 1) {
message.msgText = (roomInfo.locked ? @"房主將房間鎖定" : @"房主將房間解鎖了");
} else if (isTopicChange.unsignedIntegerValue == 1) {
message.msgText = [NSString stringWithFormat:@"房主更改了話題 %@", roomInfo.subject];
} else {
message.msgText = @"房主更改了房間信息";
}
return message;
}
- (void)addChatRoomMessage:(NSNotification*)notification msgType:(MFChatRoomMsgType)msgType msgSubType:(MFChatRoomMsgSubType)msgSubType {
MFChatRoomMessage * message = [self getChatRoomMessage:notification msgType:msgType msgSubType:msgSubType];
[self.msgArray addObject:message];
}
@end
然后在MyViewController
里
@interface MyViewController : UIViewController
@property (nonatomic, strong) MyViewModel *viewModel;
@end
@implementation MyViewController
- (MyViewModel *)viewModel {
if(_viewModel == nil) {
_viewModel = [[MyViewModel alloc] init];
}
return _viewModel;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
return self.viewModel.msgArray[indexPath.row];
}
- (void)onRoomInfoUpdateNotification:(NSNotification*)notification {
[self.viewModel addChatRoomMessage:notification msgType:kSystemType msgSubType:kPlanTextSubType];
[self.tableView reload];
}
@end
這里就進行了近一步的封裝,把和數(shù)據(jù)msgArray
的操作細節(jié)都封裝到了VM
,VC
完全不用進行復(fù)雜的數(shù)據(jù)處理工作了.同樣的想法,如果一個VC
里面同一個table
有很多Cell
,也同樣可以封裝進VM
,而VC
只關(guān)心最后得到的cell
,這樣做會減少VC
的大小,而可以更容易看明白VC
的控制細節(jié),而VM
作為一個數(shù)據(jù)的轉(zhuǎn)化工廠被VC
持有,VC
可以方便的取出View
需要的最終數(shù)據(jù).