读书笔记之Delegate中的优化

本文探讨了在iOS开发中优化代理模式的策略。通过使用`respondsToSelector:`判断代理对象是否实现可选方法,避免不必要的检测。提出将方法响应能力缓存到位域(bitfield)中,以提高程序效率。在代理的setter方法中设置并存储响应状态,调用时直接检查位域标志,减少重复检测。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们在编写代理协议时,代理协议中的方法一般都是@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个。于是,fieldA可以表示0~255之间的值,fieldD可以表示0或1这两个值。如果创建一个只有大小为1的位段的结构体,就可以把布尔值塞进一小块数据里了。

// .h文件

#import <Foundation/Foundation.h>

@protocol testDelegate <NSObject>
@optional
-(void)delegateFuncA:(NSString*)argument;
-(void)delegateFuncB:(NSString*)argument;
-(void)delegateFuncC:(NSString*)argument;
@end

@interface testClass : NSObject
@property(nonatomic, weak) id<testDelegate> delegate;
@end

// .m文件
#import "testClass.h"
@interface testClass(){
    struct {
        unsigned int delegateFuncA  : 1;
        unsigned int delegateFuncB  : 1;
        unsigned int delegateFuncC  : 1;
    } _delegateFlags;
}
@end

@implementation testClass
-(void)setDelegate:(id<testDelegate>)delegate{
    _delegate = delegate;
    _delegateFlags.delegateFuncA = [delegate respondsToSelector:@selector(delegateFuncA:)];
    _delegateFlags.delegateFuncB = [delegate respondsToSelector:@selector(delegateFuncB:)];
    _delegateFlags.delegateFuncC = [delegate respondsToSelector:@selector(delegateFuncC:)];
}
@end

在delegate的setter方法中这样缓存起来响应方法的情况。这样的话每次调用delegate的相关方法之前,就不用检测代理方是否能够响应给定的方法了,直接查询结构体中的标志即可:

if (_delegateFlags.delegateFuncA) {
    [_delegate delegateFuncA:@""];
}

在相关方法调用很多次时,值得进行这种优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值