一般我们使用代理设计
模式的时候对于@optional
修饰的方法我们一般都会在需要回调的时候使用- (BOOL)respondsToSelector:
检测一下是否响应方法调用.
首先我们知道每次需要调用的时候都
- (BOOL)respondsToSelector:
一下,也就是需要走消息传递的流程的,比较耗时.
那么,我们有什么办法可以优化一下么.
其实,代理方法都是确定的.比如在A实例中我们写了B的代理方法.并且设置了B的代理为A.那么A就能响应B的对应的方法.
根据上面的描述,其实我们可以在设置代理的时候就能把某个代理方法是否响应就能确定下来了.那么我们应该在- (void)setDelegate:
方法内缓存
下方法是否响应.
我们可以通过以下手段来缓存是否能够响应.比如我下面有俩方法.我通过下面的结构体记录一下
@implementataion
struct {
unsigned int aaa :1;
unsigned int bbb :1;
} _delegateHas;
...
@end
然后在setDelegate方法里面检测是否响应.
- (void)setDelegate:(id<XXDelegate>)delegate {
[super setDelegate:delegate];
_delegateHas.aaa = [delegate respondsToSelector:@selector(aaa)];
_delegateHas.bbb = [delegate respondsToSelector:@selector(bbb)];
}
然后其他的[delegate respondsToSelector:@selector(aaa)]或者bbb
的地方就直接替换为_delegateHas.aaa
或者是_delegateHas.bbb
.
上面的aaa与bbb后面的:
用到的是C语言的位段.就是说这个无符号int类型的aaa占用了1个二进制位.(所以存储的就是0或者是1,也就是NO或者是YES).举个例子.unsigned int aaa :n;n
就代表n个二进制位.