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>