OC中如何优化代理是否响应某个方法
2014-08-06 18:24
225 查看
看以下示例代码:if([_delegate respondsToSelector:
@selector(someClassDidSomething:)){
[_delegate someClassDidSomething];
}一般情况下,我们在写代理的时候都是这样判断某个对象有没有实现代理中的某个方法。这样固然可以,但是如果某个代理方法调用的频率非常非常高,因为在调用这个代理方法的时候,都需要做一次if判断,if判断的时候又要执行respondsToSelector:方法,所以效率会显得很低下。此时,我们可以采用缓存的办法,来进行优化。
在C语言中有一种乏人问津的特性——可以把结构体中得某个字段在内存中所占用的位数设置为特定的值。
比如:
struct data{
unsigned int fieldA : 8;
unsigned int fieldB : 4;
unsigned int fieldC : 2;
unsigned int fieldD : 1;
};在这个结构体中,fieldA占8位,所以可以表示的范围是0~255,fieldD只占一位,则可以表示的数是0和1。0和1能表示什么,很明显,可以用来表示布尔(BOOL)类型的值。
现在看优化的代码如下:
@protocol EOCNetworkFetcherDelegate
@optional
-(void)networkFetcher:(EOCNetworkFetcher *)fetcher didReceiveData:(NSData *)data;
-(void)networkFetcher:(EOCNetworkFetcher *)fetcher didFailError:(NSError *)error;
-(void)networkFetcher:(EOCNetworkFetcher *)fetcher didUpdateProgressTo:(float)progress;
@end
优化代码:
@interface EOCNetworkFetcher(){
struct{
unsigned int didReceiveData : 1;
unsigned int didReceiveData : 1;
unsigned int didReceiveData : 1;
} _delegateFlags;
}
@end
在setDelegate中,可以写以下代码,来优化:
-(void)setDelegate:(id<EOCNetworkFetcher>)delegate{
_delegate = delegate;
_delegateFlags.didReceiveData =[delegate respondsToSelector:@selector(networkFetcher:didReceiveData:)];
_delegateFlags.didFailWithError =[delegate respondsToSelector:@selector(networkFetcher:didFailWithError:)];
_delegateFlags.didUpdateProgressTo =[delegate respondsToSelector:@selector(networkFetcher:didUpdateProgressTo:)];
}
在设置完delegate以后,就可以采用_delegateFlags中的具体标志而不需要每次都调用respondsToSelector:来判断是否响应了某个方法。
if(_delegateFlags.didUpdateProgressTo){
[_delegate networkFetcher:self didUpdateProgressTo:currentProgress];
}
又涨姿势了有木有!!!
@selector(someClassDidSomething:)){
[_delegate someClassDidSomething];
}一般情况下,我们在写代理的时候都是这样判断某个对象有没有实现代理中的某个方法。这样固然可以,但是如果某个代理方法调用的频率非常非常高,因为在调用这个代理方法的时候,都需要做一次if判断,if判断的时候又要执行respondsToSelector:方法,所以效率会显得很低下。此时,我们可以采用缓存的办法,来进行优化。
在C语言中有一种乏人问津的特性——可以把结构体中得某个字段在内存中所占用的位数设置为特定的值。
比如:
struct data{
unsigned int fieldA : 8;
unsigned int fieldB : 4;
unsigned int fieldC : 2;
unsigned int fieldD : 1;
};在这个结构体中,fieldA占8位,所以可以表示的范围是0~255,fieldD只占一位,则可以表示的数是0和1。0和1能表示什么,很明显,可以用来表示布尔(BOOL)类型的值。
现在看优化的代码如下:
@protocol EOCNetworkFetcherDelegate
@optional
-(void)networkFetcher:(EOCNetworkFetcher *)fetcher didReceiveData:(NSData *)data;
-(void)networkFetcher:(EOCNetworkFetcher *)fetcher didFailError:(NSError *)error;
-(void)networkFetcher:(EOCNetworkFetcher *)fetcher didUpdateProgressTo:(float)progress;
@end
优化代码:
@interface EOCNetworkFetcher(){
struct{
unsigned int didReceiveData : 1;
unsigned int didReceiveData : 1;
unsigned int didReceiveData : 1;
} _delegateFlags;
}
@end
在setDelegate中,可以写以下代码,来优化:
-(void)setDelegate:(id<EOCNetworkFetcher>)delegate{
_delegate = delegate;
_delegateFlags.didReceiveData =[delegate respondsToSelector:@selector(networkFetcher:didReceiveData:)];
_delegateFlags.didFailWithError =[delegate respondsToSelector:@selector(networkFetcher:didFailWithError:)];
_delegateFlags.didUpdateProgressTo =[delegate respondsToSelector:@selector(networkFetcher:didUpdateProgressTo:)];
}
在设置完delegate以后,就可以采用_delegateFlags中的具体标志而不需要每次都调用respondsToSelector:来判断是否响应了某个方法。
if(_delegateFlags.didUpdateProgressTo){
[_delegate networkFetcher:self didUpdateProgressTo:currentProgress];
}
又涨姿势了有木有!!!
相关文章推荐
- OC基础day5-点语法、property、编译器指令、id万能指针、类与类的判断、判断对象是否响应指定的方法、判断类中是否有这个方法、参数方法与响应、构造方法、synthesize
- #如何用ping的方法验证代理IP是否可用
- javascript如何判断数组内元素是否重复的方法集锦
- .net C# 如何判断一个对象是否具有某个方法
- RHEL5查看gcc是否安装和如何安装gcc的方法
- 如何判断一个类是否支持某属性和方法以及如何判断IOS的版本
- 如何判断Oracle字段中是否包含中文的方法
- 网站分析系统性方法与策略:如何监测与优化网站
- 如何让用户更容易找到信息 优化网站信息架构方法谈
- 如何寻找关键词和优化关键词的方法
- 如何自我检查网站的优化是否做得到位
- 如何用最简单最快的方法判断一个BMP图片是否为黑白图片?我现在是全图片scanline 然后再加以分析,太慢了,有没有直接的函数可以做到呢?
- 如何判断团队是否真正实施Scrum -- Scrum方法二十问 (二)
- 如何判断团队是否真正实施Scrum -- Scrum方法二十问(一) Scrum 使用者强烈推荐
- 【all】 如何测试本机是否能连接到数据库的最简单的方法
- 有个输入框textbox和一个button,如何直接回车就响应button_click()方法
- 如何判断程序是否重复运行的几种方法
- 如何判断团队是否真正实施Scrum -- Scrum方法二十问
- 由浅入深CIL系列:5.抛砖引玉:判断string是否为空的四种方法的CIL代码看看效率如何?
- 如何分析一个网站的优化是否合格