iOS将数据从controller里分离出来减轻controller的压力
hifr1816
8年前
<p>今天要说的是一种代码优化的技巧,我们知道,编程一直讲求高聚合,低耦合。一般地,我们会将一个页面的 UITableviewDelegate 和 UITableviewDataSource 写在同一个controller里,如果你只有一个数据源,这样写是可以的。但假设下面这种情况,如图,一个页面有多个数据源,如果在同一个controller里写的话,一个controller同时要遵守 UITableViewDelegate,UITableviewDataSource,UICollectionDelegate,UICollectionDataSource, 然后将这些代理实现,那controller的压力是不是会变得很大呢?接下来就是减压的时刻了。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/cb82b93615ff06a1d21164a9ebbe3159.png"></p> <p style="text-align:center">两个数据源.png</p> <p>先看下项目中的效果图。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/a50a64f932b67b2484f4916822bcee90.jpg"></p> <p style="text-align:center">分离出数据.jpeg</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/b4cfec58db2985ce80713a2daf7623e1.jpg"></p> <p style="text-align:center">controller中的代理实现.jpeg</p> <p>下面以图中左边的tableview为例。</p> <p>先建一个类继承自 NSObject ,遵循 UITableviewDataSource ,并定义一个block,写两个对象方法,定义一个数组,代码如下:</p> <p>XSMutiCatagoryTableviewDataSource.h</p> <pre> <code class="language-objectivec">#import <UIKit/UIKit.h> typedef void (^MutiCatagoryTableViewCellConfigureBlock)(id cell, id item); @interface XSMutiCatagoryTableViewDataSource : NSObject <UITableViewDataSource> @property (nonatomic, copy) NSArray *items; - (id)initWithItems:(NSArray *)items cellIdentifier:(NSString *)cellIdentifier configureCellBlock:(MutiCatagoryTableViewCellConfigureBlock)configureCellBlock; - (id)itemAtIndexPath:(NSIndexPath *)indexPath; @end</code></pre> <p>XSMutiCatagoryTableviewDataSource.m</p> <pre> <code class="language-objectivec">#import "XSMutiCatagoryTableViewDataSource.h" @interface XSMutiCatagoryTableViewDataSource () @property (nonatomic, copy) NSString *cellIdentifier; @property (nonatomic, copy) MutiCatagoryTableViewCellConfigureBlock configureCellBlock; @end @implementation XSMutiCatagoryTableViewDataSource - (id)initWithItems:(NSArray *)items cellIdentifier:(NSString *)cellIdentifier configureCellBlock:(MutiCatagoryTableViewCellConfigureBlock)configureCellBlock { self = [super init]; if (self) { self.items = items; self.cellIdentifier = cellIdentifier; self.configureCellBlock = configureCellBlock; } return self; } #pragma mark - public methods - (id)itemAtIndexPath:(NSIndexPath *)indexPath { return self.items[(NSUInteger)indexPath.row]; } #pragma mark - UITableViewDataSource - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.items count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.cellIdentifier forIndexPath:indexPath]; id item = [self itemAtIndexPath:indexPath]; self.configureCellBlock(cell, item); return cell; } @end</code></pre> <p>然后就是controller里的事情了</p> <p>XSMutiCatagoryViewController.m</p> <pre> <code class="language-objectivec">#import "XSMutiCatagoryTableViewDataSource.h" @interface XSMutiCatagoryViewController () <UITableViewDelegate> @property (strong, nonatomic) XSMutiCatagoryTableViewDataSource *mutiCatagoryTableViewDataSource; @property (strong, nonatomic) UITableView *tableView; @property (strong, nonatomic) MenuBridge *menuBridge;//数据源 @end @implementation XSMutiCatagoryViewController #pragma mark - life cycle - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; CGFloat height = [UIScreen mainScreen].bounds.size.height; CGFloat width = [UIScreen mainScreen].bounds.size.width; self.tableView.frame = CGRectMake(0,64, width / 4, height-49-64); } - (void)viewDidLoad { [super viewDidLoad]; [self.view addSubview:self.tableView]; [self loadMenuData]; } #pragma mark - http menthods - (void)loadMenuData { __weak typeof(self) weakSelf = self; [MBProgressHUD showHUDAddedTo:self.view animated:YES]; XSAPIManager *manager = [XSAPIManager manager]; [manager GET:url parameters:parameters success:^(id responseObject) { //NSLog(@"分类页tableview数据%@",responseObject); weakSelf.menuBridge = [MenuBridge mj_objectWithKeyValues:responseObject]; if (weakSelf.menuBridge.data.count > 0) { weakSelf.mutiCatagoryTableViewDataSource.items = weakSelf.menuBridge.data; [weakSelf.tableView reloadData]; [weakSelf.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionBottom]; [weakSelf tableView:weakSelf.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; } [MBProgressHUD hideAllHUDsForView:weakSelf.view animated:YES]; } failure:^(NSError *error) { [MBProgressHUD hideAllHUDsForView:weakSelf.view animated:YES]; }]; } #pragma mark - getters and setters - (UITableView *)tableView { if (_tableView == nil) { _tableView = [[UITableView alloc] init]; _tableView.backgroundColor = MENU_COLOR; _tableView.separatorColor = OTHER_SEPARATOR_COLOR; [_tableView registerNib:[UINib nibWithNibName:@"XSMutiCatagoryTableViewCell" bundle:nil] forCellReuseIdentifier:tableCellId]; _tableView.delegate = self; _tableView.dataSource = self.mutiCatagoryTableViewDataSource; _tableView.rowHeight = 49.0f; } return _tableView; } - (XSMutiCatagoryTableViewDataSource *)mutiCatagoryTableViewDataSource { if (_mutiCatagoryTableViewDataSource == nil) { _mutiCatagoryTableViewDataSource = [[XSMutiCatagoryTableViewDataSource alloc] initWithItems:self.menuBridge.data cellIdentifier:tableCellId configureCellBlock:^(XSMutiCatagoryTableViewCell *cell, Menu *item) { [cell configureForMenuItem:item]; }]; } return _mutiCatagoryTableViewDataSource; }</code></pre> <p>以上。</p> <p> </p> <p>来自:http://www.jianshu.com/p/9bb0ff4d2e02</p> <p> </p>