- Objective-C 可以使用 “委托模式”(Delegate pattern)的编程设计模式来实现对象间的通信:定义一套接口,某对象若想接受另一个对象的委托,则需遵从此接口,以便成为其 “委托对象”(delegate)。Objective-C 一般利用 “协议” 机制来实现此模式。
@class EOCNetworkingFetcher;
struct {
unsigned int didReceiveData : 1;
unsigned int didFailWirhError : 1;
unsigned int didUpdateProgressTo : 1;
} _delegateFlags;
@protocol EOCNetworkingFetcherDelegate <NSObject>
@optional
- (void)newworkingFetcher:(EOCNetworkingFetcher *)fetcher
didRecevieData:(NSData *)data;
@end
@interface EOCNetworkingFetcher : NSObject
@property (nonatomic, weak) id <EOCNetworkingFetcherDelegate> delegate;
@end
- 如果要在委托对象上调用可选方法,那么必须提前使用类型信息查询方法,判断这个委托对象能否响应相关的选择子。
if ([self.delegate respondsToSelector:@selector(newworkingFetcher:didRecevieData:)]) {
NSData *data;
[self.delegate newworkingFetcher:self didRecevieData:data];
}
- 每次调用方法都会判断一次,其实除了第一次检测的结构有用,后续的检测很有可能都是多余的,因为委托对象本身没变,不太可能会一下子不响应,一下子响应的,所以我们这里可以把这个委托对象能否响应某个协议方法记录下来,以优化程序效率。
- 将方法响应能力缓存起来的最佳途径是使用 “位段”(bitfield)数据类型。我们可以把结构体中某个字段所占用的二进制位个数设为特定的值。
位段,C语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为“位段”或称“位域”( bit field) 。
struct data {
unsigned int filedA : 8;
unsigned int filedB : 4;
unsigned int filedC : 2;
unsigned int filedD : 1;
}
- filedA 位段占用8个二进制位,filedB 位段占用4个二进制位,filedC 位段占用2个二进制位,filedD位段占用1个二进制位。filedA 就可以表示0至255之间的值,而filedD 则可以表示0或1这两个值。
- 我们可以像filedD 这样子,创建大小只有1的位段,这样子就可以把Boolean 值塞入这一小块数据里面,这里很适合这样子做。
利用位段就可以清楚的表示delegate 对象是否能响应协议中的方法。
struct {
unsigned int didReceiveData : 1;
unsigned int didFailWirhError : 1;
unsigned int didUpdateProgressTo : 1;
} _delegateFlags;
_delegateFlags.didReceiveData = 1;
if (_delegateFlags.didReceiveData) {
// yes
NSData *data;
[self.delegate newworkingFetcher:self didRecevieData:data];
}else {
// no
if ([self.delegate respondsToSelector:@selector(newworkingFetcher:didRecevieData:)]) {
}
}