zoukankan      html  css  js  c++  java
  • 第23条:通过委托与数据源协议进行对象间通信

    Objective-C语言特性:协议protocol),它与Java的“接口”(interface)类似。

    Objective-C不支持多继承,但可以把类的实现方法定义在协议里面。

    协议最为常见的用途是实现委托模式(Delegate pattern)

    委托模式(Delegate pattern):

    用来实现对象间的通信,

    该模式的主旨是:定义一套接口,某对象若想授受另一个对象的委托,则需遵从此接口,以便成为其“委托对象”(delegate)。而这“另一对象”则可以给其委托对象回传一些消息,也可以在发生相关事件时通知委托对象。

    此模式可以将数据与业务逻辑解耦

    数据源(data source)与委托(delegate)对象分别处理。

    数据源:数据源流向类(输入),

    委托:从类流向受委托者(输出)。

    数据源和受委托者可以是两个不同的对象。然而一般情况下,都用同一个对象来扮演这两种角色。

    委托协议命名

    类名+Delegate(后缀)

    有了协议后,类就可以用一个属性来存放其委托对象了。

    例:

    @property(nonatomic, weak) id<类名+Delgate> delegate;

    // 此处用weak表示“百拥有关系”(nonowning relationship)。

    // 还可以用unsafe_unretained

    // weak与unsafe_unretained的区别:如果需要在相关对象销毁时自动清空(autoniling,参见第6条),则用weak。反之用unsafe_unretained。

    @optional关键字(可选的):

    在委托对象上调用可选方法时必须提前使用类型信息查询方法(参见第14条)来判断这个委托对象能否响应相关选择子。

    例:if([_delegate respondsToSelector:@selector(委托方法)]) {

      [_delegate 委托方法];

    }

    如果非可选方法,则不需要。

    关于选择子判断的优化:

    有时除了第一次检测的结果有用之外,后续的检测可能是多余的。对于频繁的检测,也消耗性能

    对此可以优化:把委托对象能否响应某个协议方法这一信息缓存起来。

    位段:

    将方法响应能力缓存起来的最佳人途径是使用“位段”(bitfield数据类型。这是一项无人问津的C语言特性

    结构体中某个字段所占用的二进制位个数设为特定的值。

    例:struct data {

      unsigned int fieldA: 8; // 表示0~255之间的值

      unsigned int fieldB: 4;

      unsigned int fieldB: 1; // 表示0或1

    }

    这样就可以嵌入一个含有位段的结构体作为实例变量,而结构体中的每个位段表示delegate对象是否实现了协议中的相关方法。(类似字典

    例:struct {

      unsigned int didReceiveData: 1;

      unsigned int didFailWithError: 1;

      unsigned int didUpdateProgressTo: 1;

    } _delegateFlags;

    -(void)setDelegate:(id<协议> delegate){

      _delegate = delegate;

      _delegate.didReceiveData = [@delegate respondsToSelector:@selector(方法)]; // 值为:0或1

      // ……

    }

    if(_delegate.didReceiveData) {

      [_delegate 方法]  

    }

    delegate对象可以有多个,所以在定义或调用时,应该把发起委托的类或实例加入进去。

    例:- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

      if(tableView == tableViewA){

      }else if(tableView == tableViewA){

      }

    }

  • 相关阅读:
    一个简单的knockout.js 和easyui的绑定
    knockoutjs + easyui.treegrid 可编辑的自定义绑定插件
    Knockout自定义绑定my97datepicker
    去除小数后多余的0
    Windows Azure Web Site (15) 取消Azure Web Site默认的IIS ARR
    Azure ARM (1) UI初探
    Azure Redis Cache (3) 创建和使用P级别的Redis Cache
    Windows Azure HandBook (7) 基于Azure Web App的企业官网改造
    Windows Azure Storage (23) 计算Azure VHD实际使用容量
    Windows Azure Virtual Network (11) 创建VNet-to-VNet的连接
  • 原文地址:https://www.cnblogs.com/Pikdays/p/5739786.html
Copyright © 2011-2022 走看看