23 通过委托与数据源协议进行对象间通信 总结:
委托模式的常规委托模式中,信息从类Class流向受委托者delegate。数据源模式,信息从数据源datasource流向class。数据源和受委托者可以是两个不同对象。
有时候一个可选择方法可能在一个生命期中多次调用,如果每次都检查委托对象是否能响应选择子,那就显得多余了。可以使用位段(bitfield)数据类型将方法响应能力缓存起来。
c语言特性:我们可以把结构体中的某个字段所占用的二进制位数设为特定的值。
struct data{
unsigned int fieldA : 8;
unsigned int fieldB : 4;
unsigned int fieldC : 2;
unsigned int fieldD : 1;
}; 这里fieldA位段占用8个二进制位,可以表示0~255之间的值,fieldB占用4个,fieldC占用2个,fieldD占用1个,可以表示0、1。
所以当我们可以这样做
struct{
unsigned int didReceiveData :1;
unsigned int didFailWithError :1;
unsigned int didUpdateProgressTo :1;
}_delegateFalags;
在方法要调用很多次时,值得进行这种优化,如果要频繁通过数据源协议从数据源中获取多分相互独立的数据,那么这项优化技术基友可能会提高程序效率。
24 将类的实现代码分散到便于管理的数个分类之中 总结:
易于管理,便与调试。
将应视为“私有”的方法归入名为Private的分类中,以隐藏实现细节。使用分类机制把类的实现代码划分成易于管理的小块。(具体)
25 总是为第三方类的分类名称加前缀 总结:
向第三方类中添加分类时,总应给其名称和其中的方法名加上专用前缀。
分类中晚加载的方法会覆盖先加载的同名方法。(具体)
26 勿在分类中声明属性 总结:
属性是封装数据的方式,除了class-continuation分类之外,其他分类都无法向类中新增实例变量,因此,无法把实现属性所需的实例变量合成出来。应将分类机制理解为一种手段,目的在于扩展分类的功能,而非封装数据。
要把数据所用的全部属性都定义在主接口中。
在class-continuation分类之外的其他分类中,可以定义存取方法,但尽量不要定义属性。
27 使用class-continuation分类(其实是类扩展)隐藏实现细节 总结:
oc动态消息系统的工作方式决定了其不可能实现真正的私有方法或私有实例变量。在类扩展中定义的实例变量并非真的私有,因为在运行期总可以调用某些方法绕过此限制,不过,从一般意义上来说,它们还是私有的。
编写OC++代码时“class-continuation分类”也尤为有用。oc++是oc与c++的混合体,其代码可以用这两种语言来编写。由于兼容性原因,游戏后端一般用c++来写。另外有时候要使用的第三方库可能只有c++绑定,此时也必须使用c++编码。通过class-continuation分类向类中新增实例变量。
如果某属性在主接口中声明为“只读”,而类的内部又要用设置方法修改此属性,那么就在class-continuation分类中将其扩展为“可读写”。把私有方法的原型声明在class-continuation分类里面。若想使类所遵循的协议不为人所知,则可于class-continuation分类中声明。
28 通过协议提供匿名对象 总结:
协议可在某种程度上提供匿名类型id。具体的对象类型可以淡化成遵从某协议的id类型,协议里规定了对象所应实现的方法。使用匿名对象来隐藏类型名称(或类名)。如果具体类型不重要,重要的是对象能够响应特定方法,那么可使用匿名对象来表示。
对于字典来说,键的标准内存管理语义是设置时拷贝,而值的语义则是设置时保留。
- (void)setObject:(id)object forKey:(id<NSCopying>)key;