• 第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){

      }

    }

  • 相关阅读:
    Struts2升级注意事项
    使用HttpClient获取网页源码
    The method getJspApplicationContext(ServletContext) is undefined for the type JspFactory解决方案
    IBatis常见错误集锦
    JPush极光推送Java服务器端API
    JS去空trim
    Jquery常用操作
    适配器模式(Adapter)
    常见数据库设计(3)——历史数据问题之多记录变更
    VS2008 工具箱都是textbox(报表设计时)
  • 原文地址:https://www.cnblogs.com/Pikdays/p/5739786.html
Copyright © 2020-2023  润新知