我们在编写代理协议时,代理协议中的方法一般都是@optional的,代理方不一定实现了代理协议中的所有方法。那么我们在代理方上调用可选方法时候,最好提前使用类型信息查询方法来判断这个委托对象是否能够相应相关协议方法:
if (delegate respondsToSelector:@selector(selector)) {
[delegate selector];
}
用 respondsToSelector: 来判断代理方是否实现了相关的方法,如果实现了就调用,如果没有实现就不执行任何操作。
在实现代理模式时,如果协议中的方法是可选的,就会写出一大批类似上面这样的代码来。即使很容易就能用代码查出某个代理方能否相应特定的方法,可是如果频繁执行此操作的话,那么除了第一次检测的结果有用之外,后续的检测可能都是多余的。如果代理方本身没变,那么不大可能会突然响应某个原来不能响应的方法,也不太会突然无法响应某个原来可以响应的方法。因此,我们可以吧代理方能否响应某个协议方法这一信息缓存起来,以优化程序效率。
将方法响应能力缓存起来的最佳途径是使用"位域"(又称位段):
struct data {
unsigned int fieldA : 8;
unsigned int fieldB : 4;
unsigned int fieldC : 2;
unsigned int fieldD : 1;
}
这data这个结构体中,field位段占用8个二进制位,fieldB占用4个,fieldC占用2个,fieldD占用1个。于是,