标签:mvc model view controller 开发模式
好久没有写文章了,上一篇对于初学者可能比较有用的文章吧……
我的入行语言是Java、JSP,比较强调MVC模式,所以对MVC还是比较了解的。因此后来转入iOS开发,在模式上就没有那么纠结,但是对于很多初入编程领域的人来说可能会比较困惑,下面用一个简单的列表例子来说一下iOS开发当中的MVC模式。
首先,新建一个工程,在工程中新建两个UIViewController的子类,如图:
我将用这两个类来示例非MVC(MainViewController)和MVC(SecondViewController)模式,为了可读性和解释性更强,例子当中没有用IB,所有界面用代码写出(这也是我个人开发中的习惯)。
其中MainViewController.m代码如下
#import "MainViewController.h" #import "ASIFormDataRequest.h" #define kScreenWidth [UIScreen mainScreen].bounds.size.width #define kScreenHeight [UIScreen mainScreen].bounds.size.height @interface MainViewController () @property (nonatomic, retain) NSMutableArray *dataArray; @end @implementation MainViewController { UITableView *_tableView; } - (void)viewDidLoad { [super viewDidLoad]; [self setupDefaultValue]; [self setupDefaultView]; [self request]; } - (void)setupDefaultValue { self.dataArray = [NSMutableArray array]; } - (void)setupDefaultView { _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight) style:UITableViewStylePlain]; _tableView.delegate = self; _tableView.dataSource = self; [self.view addSubview:_tableView]; } - (void)request { NSString *urlString = @"http://beautifulword.sinaapp.com/results.php"; NSURL *url = [NSURL URLWithString:urlString]; ASIFormDataRequest *_request = [ASIFormDataRequest requestWithURL:url]; __weak ASIFormDataRequest *request = _request; [request setCompletionBlock:^{ NSData *data = request.responseData; NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; NSArray *array = [dict objectForKey:@"Profile"]; for (NSDictionary *itemDict in array) { [self.dataArray addObject:itemDict]; } [_tableView reloadData]; }]; [request setFailedBlock:^{ NSLog(@"failed"); }]; [request startAsynchronous]; } #pragma mark- UITableView Delegate - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.dataArray.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellID = @"cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellID]; } NSDictionary *dict = self.dataArray[indexPath.row]; cell.textLabel.text = dict[@"name"]; cell.detailTextLabel.text = dict[@"age"]; return cell; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @end
对于MVC模式,最核心的东西是控制器(Controller),在iOS工程当中,我们可以很容易找到它,从名字就能看出来,比如MainViewController,至于它的作用,可以从苹果官方的开发文档中找到:
View controllers are the foundation of your app’s internal structure. Every app has at least one view controller, and most apps have several. Each view controller manages a portion of your app’s user interface as well as the interactions between that interface and the underlying data. View controllers also facilitate transitions between different parts of your user interface.
我们来看MainViewController,这个类非常简单,逻辑也非常清楚,其中Model就是网络请求数据,View就是UITableView和UITableViewCell。第一步,先把Model拆分出来,我们新建一个Model类:
UserModel.h文件如下:
#import <Foundation/Foundation.h> @interface UserModel : NSObject @property (nonatomic, copy) NSString *name; @property (nonatomic, copy) NSString *age; @property (nonatomic, copy) NSString *gender; @property (nonatomic, copy) NSString *phone; @property (nonatomic, retain) NSMutableDictionary *dict; @end
#import "UserModel.h" @implementation UserModel - (id)init { if (self == [super init]) { self.dict = [[NSMutableDictionary alloc] init]; } return self; } - (id)valueForUndefinedKey:(NSString *)key { return @""; } - (void)setValue:(id)value forUndefinedKey:(NSString *)key { [self.dict setObject:value forKey:key]; } @end
- (void)request { NSString *urlString = @"http://beautifulword.sinaapp.com/results.php"; NSURL *url = [NSURL URLWithString:urlString]; ASIFormDataRequest *_request = [ASIFormDataRequest requestWithURL:url]; __weak ASIFormDataRequest *request = _request; [request setCompletionBlock:^{ NSData *data = request.responseData; NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; self.dataArray = [dict objectForKey:@"Profile"]; [_tableView reloadData]; }]; [request setFailedBlock:^{ NSLog(@"failed"); }]; [request startAsynchronous]; } - (void)setDataArray:(NSMutableArray *)dataArray { for (NSDictionary *itemDict in dataArray) { UserModel *model = [[UserModel alloc] init]; for (NSString *key in itemDict) { [model setValue:itemDict[key] forKey:key]; } [_dataArray addObject:model]; } }
一般情况下呢,我习惯自定义Cell,便于以后维护,接下来,新建一个TableViewCell的子类UserCell,.h文件如下:
#import <UIKit/UIKit.h> #import "UserModel.h" @interface UserCell : UITableViewCell @property (nonatomic, retain) UserModel *model; @end
#import "UserCell.h" #define kScreenWidth [UIScreen mainScreen].bounds.size.width #define kScreenHeight [UIScreen mainScreen].bounds.size.height @implementation UserCell { UILabel *_nameLabel; UILabel *_ageLabel; UILabel *_genderLabel; UILabel *_phoneLabel; } - (void)awakeFromNib {} - (UserCell *)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { _nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth/4, 40)]; _nameLabel.textColor = [UIColor blackColor]; _nameLabel.textAlignment = NSTextAlignmentCenter; [self.contentView addSubview:_nameLabel]; _ageLabel = [[UILabel alloc] initWithFrame:CGRectMake(kScreenWidth/4, 0, kScreenWidth/4, 40)]; _ageLabel.textColor = [UIColor blackColor]; _ageLabel.textAlignment = NSTextAlignmentCenter; [self.contentView addSubview:_ageLabel]; _genderLabel = [[UILabel alloc] initWithFrame:CGRectMake(kScreenWidth/4*2, 0, kScreenWidth/4/2, 40)]; _genderLabel.textColor = [UIColor blackColor]; _genderLabel.textAlignment = NSTextAlignmentCenter; [self.contentView addSubview:_genderLabel]; _phoneLabel = [[UILabel alloc] initWithFrame:CGRectMake(kScreenWidth/4*3-kScreenWidth/4/2, 0, kScreenWidth/4+kScreenWidth/4/2, 40)]; _phoneLabel.textColor = [UIColor blackColor]; _phoneLabel.textAlignment = NSTextAlignmentCenter; [self.contentView addSubview:_phoneLabel]; } return self; } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; } - (void)setModel:(UserModel *)model { _model = model; _nameLabel.text = model.name; _ageLabel.text = model.age; _genderLabel.text = model.gender; _phoneLabel.text = model.phone; } @end
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellID = @"cell"; UserCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; if (cell == nil) { cell = [[UserCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID]; } cell.model = self.dataArray[indexPath.row]; return cell; }
MVC分离完成之后,将代码整理到另一个类SecondViewController中,如下:
#import "SecondViewController.h" #import "ASIFormDataRequest.h" #import "UserModel.h" #import "UserCell.h" #define kScreenWidth [UIScreen mainScreen].bounds.size.width #define kScreenHeight [UIScreen mainScreen].bounds.size.height @interface SecondViewController () @property (nonatomic, retain) NSMutableArray *dataArray; @end @implementation SecondViewController { UITableView *_tableView; } - (void)viewDidLoad { [super viewDidLoad]; [self setupDefaultValue]; [self setupDefaultView]; [self request]; } - (void)setupDefaultValue { _dataArray = [NSMutableArray array]; } - (void)setupDefaultView { _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight) style:UITableViewStylePlain]; _tableView.delegate = self; _tableView.dataSource = self; [self.view addSubview:_tableView]; } - (void)request { NSString *urlString = @"http://beautifulword.sinaapp.com/results.php"; NSURL *url = [NSURL URLWithString:urlString]; ASIFormDataRequest *_request = [ASIFormDataRequest requestWithURL:url]; __weak ASIFormDataRequest *request = _request; [request setCompletionBlock:^{ NSData *data = request.responseData; NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; self.dataArray = [dict objectForKey:@"Profile"]; [_tableView reloadData]; }]; [request setFailedBlock:^{ NSLog(@"failed"); }]; [request startAsynchronous]; } #pragma mark- UITableView Delegate - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.dataArray.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellID = @"cell"; UserCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; if (cell == nil) { cell = [[UserCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID]; } cell.model = self.dataArray[indexPath.row]; return cell; } - (void)setDataArray:(NSMutableArray *)dataArray { for (NSDictionary *itemDict in dataArray) { UserModel *model = [[UserModel alloc] init]; for (NSString *key in itemDict) { [model setValue:itemDict[key] forKey:key]; } [_dataArray addObject:model]; } } @end
示例的源码地址:MVCTest on github
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:mvc model view controller 开发模式
原文地址:http://blog.csdn.net/zwf_apple/article/details/47775557