zoukankan      html  css  js  c++  java
  • 轻量化ViewControllers,读文章做的总结

    推荐一个网站 http://objccn.io/ 我这两天才开始看 获益匪浅

    看了第一篇文章 《更轻量的View Controllers》感觉写的不错 感觉作者 原文地址 http://objccn.io/issue-1-1/

    示例项目的代码有点旧 Xcode6运行出错 懒的理了 所以我大概模仿他写了一点测试代码 运行环境Xcode7/iOS9

    轻量化ViewControllers 顾名思义 就是把ViewController的代码进行简化 让控制器更简单 更清晰

    一、把DataSource和其他potocols分离出控制器

    因为做项目很多控制器都是TableViewController,所以必须要有数据源(TableViewDataSource)输入,一般DataSource的3个方法都在控制器里

    我们的目的就是要把他分离出来,方法就是自定义一个类,然后控制器调用这个类

    并且这个数据源类是通用的,别的TableViewController或者有定义了tableView/collectionView的控制器都可以调用

    自定义ArrayDataSource类

    1.定义一个Block,用于传递cell和数据

    typedef void (^TableViewCellPassBlock)(id cell,id item);

    2.定义一个方法给控制器调用,用于初始化ArrayDataSource类(需要暴露在.h文件中)

    @property(nonatomic,strong) NSArray *items;

    @property(nonatomic,copy) NSString *cellIdentifier;

    @property(nonatomic,copy) TableViewCellPassBlock passBlock;

    /**

    
    

     *  初始化数据源的方法

     *  @param anItems         用于接受数据的数组

     *  @param aCellIdentifier 接收cellID

     *  @param aPassBlock      接收传递的Block

     */

    - (id)initWithItems:(NSArray *)anItems

      cellIdentifier:(NSString *)aCellIdentifier

     passBlock:(TableViewCellPassBlock)aPassBlock
    {
        self = [super init];
        if(self){
    self.items
    = anItems; self.cellIdentifier = aCellIdentifier; self.passBlock = [aPassBlock copy]; } return self; }

    3.然后就是数据源的方法

    /** 这个方法找出数组的数据 后面要用到*/
    - (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.passBlock(cell, item);
        return cell;
    }

    ArrayDataSource类就这样定义完成了

    接下来是控制器的调用

    只需要写以下几行代码便可以设置tableView的数据源,不用每个控制器都写那三个方法

        //数组传数据是接下来要简化的,后面会详细说明
      NSArray *arr = [AppDelegate sharedDelegate].returnModel.returnData; //使用Block回调,传递cell和模型数据 TableViewCellPassBlock passBlock = ^(TestModelCell *cell,TestModel *model){
        //测试方法,只是传递model给cell,这个方法用分类写的,自定义cell的分类 [cell setName:model]; };
      //初始化并设置tableView的数据源 self.dataSource
    = [[ArrayDataSource alloc] initWithItems:arr cellIdentifier:@"TestModelCell" passBlock:passBlock]; self.tableView.dataSource = self.dataSource;

    二、将业务逻辑放到model中

    一些跟控制器无关的代码可以放到模型中

    测试代码我写了一个TestModel,只有一个属性和一个初始化方法

    @property(nonatomic,copy) NSString *name;
    
    - (instancetype)initWithName:(NSString *)name;

    然后又写了一个model,因为要返回数据所以我叫ReturnModel

    在.h文件中暴露的方法

    //类方法,创建的时候用这个方法
    + (instancetype)returnModel;
    //这个方法用于返回数据
    - (NSArray *)returnData;

    然后在.m文件中

    + (instancetype)returnModel
    {
        return [[self alloc] init];
    }
    
    - (id)init
    {
        self = [super init];
        if (self) {
      
        //调用方法执行业务逻辑的方法 [self doSomething]; }
    return self; }
    //可以在这个方法中执行与控制器无关的业务逻辑
    - (void)doSomething { NSLog(@"try to do something"); }

    //在这个方法中返回模型数据,数据略

    - (NSArray *)returnData

    {

      NSArray *arr = [[NSArray alloc] initWithObject:...];

      return arr;

    }

    思路就是在返回数据的模型类中执行业务逻辑,在创建类的时候执行

    在AppDelegate中添加方法和属性,并且暴露在.h文件中

    + (instancetype)sharedDelegate
    {
        return [UIApplication sharedApplication].delegate;
    }
    
    @synthesize returnModel = _returnModel;
    
    - (ReturnModel *)returnModel
    {
        if (_returnModel == nil) {
            _returnModel = [ReturnModel returnModel];
        }
        return _returnModel;
    }

    所以控制器直接调用方法得到数据

    NSArray *arr = [AppDelegate sharedDelegate].returnModel.returnData;

    这时候控制器已经很简化了

    可以把网络请求也放在model层

    最后吐槽一句博客园的代码高亮好难看

  • 相关阅读:
    GET和POST两种基本请求方法的区别
    GET与POST类型接口
    TCP连接与断开详解(socket通信)
    QC02
    QC01
    tcp三次握手和四次挥手
    ssh整合
    redis主从切换
    缓存解释(一级缓存,二级缓存)
    cxf整合spring代码
  • 原文地址:https://www.cnblogs.com/zyb428/p/4875563.html
Copyright © 2011-2022 走看看