iOS-MVC设计模式
MVC的设计模式就本质就时把类的功能进行分类设计,斯坦福大学的老头子在iOS课程中说过,View不关心数据实体,view通过代理通知Controller自己被操作了,让Controller来决定程序的运行,如逻辑跳转或者页面跳转;Model不关心UI,Model负责数据实体的管理如从网络上获取数据实体,一般设计为单例模式,对数据实体的增加删除修改,而这些操作Model通过通知中心通知Controller,Controller通过监听对应的通知来调用对应的操作方法来在主线程更新UI。View和Model不能直接通信。它们都通过Controller来实现通信,Controller就相当于View和Model的桥梁。
简单的MVC设计如下:(代码有注释)
Model的设计:
model头文件:
#import <Foundation/Foundation.h>
extern NSString *const entityAddNotification;
extern NSString *const entityDeleteNotification;
@interface ModelInstance : NSObject
+(ModelInstance *)sharedObject;
-(void)addDataEntity:(id)entity;
-(void)removeDataEntity:(id)entity;
@end
model实现文件:
#import "ModelInstance.h"
//MVC中model层改变时的通知常量,通过通知中心通知MVC中的Controller层
extern NSString *const entityAddNotification=@"addNotification";
extern NSString *const entityDeleteNotification=@"deleteNotification";
static ModelInstance *_shareObject;
@implementation ModelInstance{
NSMutableArray *dataQueue;
}
+(ModelInstance *)sharedObject{
if (_shareObject == nil)//保证静态_shareObject指针只被初始化一次
_shareObject = [[self alloc] init];
return _shareObject;
}
-(instancetype)init{
if (self = [super init]) {
}
return self;
}
//添加Model实体,就会发送添加实体通知,告诉MVC中的Controller
-(void)addDataEntity:(id)entity{
//发送添加的通知
NSLog(@"------ %s",__func__);
[[NSNotificationCenter defaultCenter] postNotificationName:entityAddNotification object:entity];
}
//删除Model实体,就会发送删除实体通知,告诉MVC中的Controller
-(void)removeDataEntity:(id)entity{
//发送删除的通知
NSLog(@"------ %s",__func__);
[[NSNotificationCenter defaultCenter] postNotificationName:entityDeleteNotification object:entity];
}
@end
view层的设计:
view层的头文件:
#import <UIKit/UIKit.h>
@class ViewInstance;
//MVC设计模式中的View层的代理,当用户操作view时,它会通过deleagte调用controller中的代理方法,这样controller就可以做相应的处理
@protocol ViewInstanceDelegate <NSObject>
//controller要实现改方法
-(void)touchViewInstance:(ViewInstance *)view;
@end
@interface ViewInstance : UIView
//MVC中的view代理,delegate指针一般指向实现代理的方法的Controller实例
@property (nonatomic,assign)id<ViewInstanceDelegate> delegate;
@end
view层的实现文件:
#import "ViewInstance.h"
@implementation ViewInstance
//当view被触摸时掉用
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(@"------ %s",__func__);
if ([self.delegate respondsToSelector:@selector(touchViewInstance:)]) {
//当view层被操作时,调用代理的方法,也就是调用controller中实现了view协议的方法
[self.delegate touchViewInstance:self];
}
}
@end
controller层的设计:
controller头文件:
#import <UIKit/UIKit.h>
@interface ControllerInstance : UIViewController
@end
controller实现文件:
#import "ControllerInstance.h"
#import "ModelInstance.h"
#import "ViewInstance.h"
@interface ControllerInstance ()<ViewInstanceDelegate>
@end
@implementation ControllerInstance
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//监听MVC中数据源改变的通知
[self addDataModelNotification];
//新建view
ViewInstance *vInstance = [[ViewInstance alloc]initWithFrame:CGRectMake(40, 40, 100, 100)];
//设置view的代理
vInstance.delegate = self;
vInstance.backgroundColor = [UIColor redColor];
[self.view addSubview:vInstance];
//模拟从MVC中的增加和删除操作
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(20 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//二十秒后模拟添加操作
[[ModelInstance sharedObject] addDataEntity:nil];
//二十秒之后模拟删除操作
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(20 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[[ModelInstance sharedObject] removeDataEntity:nil];
});
});
}
//监听Model改变的通知
-(void)addDataModelNotification{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addEntityNotification) name:@"addNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deleteEntityNotification) name:@"deleteNotification" object:nil];
}
//对应添加实体通知的操作,一般用来在主线程更新UI
-(void)addEntityNotification{
NSLog(@"------ %s",__func__);
NSLog(@"数据源有删除动作,你应该在主线程同步UI");
}
//对应删除实体通知的操作,一般用来在主线程更新UI
-(void)deleteEntityNotification{
NSLog(@"------ %s",__func__);
NSLog(@"数据源有删除动作,你应该在主线程同步UI");
}
//view被触摸之后调用,一般用来同步数据
-(void)touchViewInstance:(ViewInstance *)view{
NSLog(@"------ %s",__func__);
NSLog(@"view instance被触摸了你可以做相应的事了,如改变数据源");
}
@end
运行结果:运行操作20秒左右后的输出,又20秒左右之后的输出,触摸视图时的输出如下:
模拟添加的输出结果:
2015-04-02 22:49:57.788 Target_action[1614:65387] ------ -[ModelInstance addDataEntity:]
2015-04-02 22:49:57.789 Target_action[1614:65387] ------ -[ControllerInstance addEntityNotification]
2015-04-02 22:49:57.789 Target_action[1614:65387] 数据源有删除动作,你应该在主线程同步UI
模拟删除的输出结果:
2015-04-02 22:50:19.789 Target_action[1614:65387] ------ -[ModelInstance removeDataEntity:]
2015-04-02 22:50:19.789 Target_action[1614:65387] ------ -[ControllerInstance deleteEntityNotification]
2015-04-02 22:50:19.789 Target_action[1614:65387] 数据源有删除动作,你应该在主线程同步UI
触摸视图的输出结果
2015-04-02 22:50:50.598 Target_action[1614:65387] ------ -[ViewInstance touchesEnded:withEvent:]
2015-04-02 22:50:50.599 Target_action[1614:65387] ------ -[ControllerInstance touchViewInstance:]
2015-04-02 22:50:50.599 Target_action[1614:65387] view instance被触摸了你可以做相应的事了,如改变数据源
小结: