OC中如何优化代理是否响应某个方法

看以下示例代码:

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];
}
时间: 2024-08-09 10:26:55

OC中如何优化代理是否响应某个方法的相关文章

1218.1——OC中的常见关键字及一些基本方法

OC常见的关键字介绍: @ 看到这个关键字,我们就应该想到,这是Object-C对C语言的扩展,例如@interface XXX. @interface 声明类 @implementation 实现类 @protocol 声明协议 @optional 与@protocol配合使用,说明协议中的某个或者某几个方法可以不实现 @required 与@protocol配合使用,说明协议中的某个方法或者某几个方法必须实现 @end 与@interface ,@implementation,@protoc

OC中保存自定义类型对象的持久化方法

OC中如果要将自定义类型的对象保存到文件中,必须进行以下三个条件: 想要把存放自定义类型的数组进行 持久化(就是将内存中的临时数据以文件<数据库等>的形式写到磁盘上)必须满足: 1. 自定义对象必须要序列化(将数据有序的存放) 2. 需要使用归档来进行持久化 3. 如果要加载持久化文件需要进行反序列化(就是将有序存放的数据读取并变成自定义对象) 第一要将自定义类型序列化以及第三步并将文件反序列化必须实现OC中的  <NSCoding>协议. 以Student类为例 @interfa

OC中协议、代理

Boss类的声明文件 #import <Foundation/Foundation.h> @protocol BossDelegate -(void)bookTicket;//预定机票 -(void)bookRoom;//预定房间 -(void)notify;//开会 @end @interface Boss : NSObject @property(nonatomic,weak)id<BossDelegate>delegate; -(void)travel;//旅行 -(void

OC -- (SEL)oc中消息传递机制-附:对performSelector方法的扩充

原文地址: http://www.cnblogs.com/ygm900/archive/2013/01/16/2862676.html 各种语言都有些传递函数的方法:C语言中可以使用函数指针,C++中有函数引用.仿函数和lambda,Objective-C里也有选择器(selector)和block.不过由于iOS SDK中的大部分API都是selector的方式,所以本文就重点讲述selector了.Objective-C和我接触过的其他面向对象的语言不同,它强调消息传递,而非方法调用.因此你

OC中自定义属性与系统属性冲突解决方法

Xcode中经常我们自己定义的一些属性会和系统的某些属性冲突,坑爹的是你根本不知道系统的这个属性到底是什么玩意,并且编译器还会报警告,对于有强迫症的同学来说,太折磨了.下面提供一个解决方法: 编译器警告: Auto property synthesis will not synthesize property 'description' 这是说编译器自动给你自定义的属性合成getter和setter的时候将会在它的父类上实现,而你会一脸懵逼不知道咋回事,其实只要添加 @dynamic告诉编译器这

OC中快速创建NSNumber NSDictionary NSArray的方法

NSNumber: @()     @小括号 或者        NSNumber * num = @3;    NSValue * value = @4; NSDictionary :@{} @大括号 NSArray :@[] @中括号

OC中的代理模式

OC中的代理模式,关于代理模式,如果还有同学不太清楚的话,就自己去补充知识了,这里就不做介绍了,这里只介绍OC中是如何实现代理模式的.这里举一个简单的例子:小孩类,护士类,保姆类,其中小孩类有两个方法:wash和play这里代理对象就是:护士类.保姆类,小孩类是被代理对象.看一下代码:首先看一下小孩类:Children.h[objc]  view plaincopy 1. //   2. //  Children.h   3. //  12_DesignStyle   4. //   5. //

OC学习篇之---代理模式

在前一篇文章我们介绍了OC中的协议的概念:http://blog.csdn.net/jiangwei0910410003/article/details/41776015,这篇文章我们就来介绍一下OC中的代理模式,关于代理模式,如果还有同学不太清楚的话,就自己去补充知识了,这里就不做介绍了,这里只介绍OC中是如何实现代理模式的. 这里举一个简单的例子: 小孩类,护士类,保姆类,其中小孩类有两个方法:wash和play 这里代理对象就是:护士类.保姆类,小孩类是被代理对象. 看一下代码: 首先看一

OC中NSFileManager类 和 copy一些用法

一:NSFileManager的使用 1, 概念:用来管理文件系统,它可以用来进行常见的文件\文件夹的操作(拷贝.剪切.创建等) NSFileManager 使用了单例模式singleton 使用defaultManager方法可以获取那个单例对象 2, 1>常见判断 //1,判断文件或文件夹是否存放 // NSFileManager *fileManager = [NSFileManager defaultManager]; // NSString *path = @"/Users/ll