标签:类对象 网络 ice sed 初始化 turn null github 路径
Objective-C 语言实现了观察者模式(Key Value Observing, KVO),并提供了简单的使用接口。
供给使用者方便的注册观察者,注册观察方法,移除观察者。
/* 方法的接收者 objectA 是被观察者 objectB 观察的对象 方法的第一个参数 objectB 是注册到 objectA 上的观察者 方法的第二个参数 @”property“ 是被观察者 objectB 监听的属性,当该属性发生改变时,通知观察者做出反应 options: 有4个值,分别是: NSKeyValueObservingOptionOld 把更改之前的值提供给处理方法 NSKeyValueObservingOptionNew 把更改之后的值提供给处理方法 NSKeyValueObservingOptionInitial 把初始化的值提供给处理方法,一旦注册,立马就会调用一次。通常它会带有新值,而不会带有旧值。 NSKeyValueObservingOptionPrior 分2次调用。在值改变之前和值改变之后。 */ [objectA addObserver:objectB forKeyPath:@"property" options:NSKeyValueObservingOptionNew context:nil];
在观察者 objectB 的实现文件中添加观察方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)contex // 在这里添加处理改变的逻辑 }
//删除指定的key路径监听器 [self.person removeObserver:self forKeyPath:@"name"]; //删除指定的key路径监听器,只是多了context参数 [self.person removeObserver:self forKeyPath:@"name" context:nil];
AFNetworking 是 iOS 开发中使用最多的第三方网络库,封装了 iOS 原生网络请求。
其中使用了大量 KVO 来对属性改变做出反应。
代码地址 https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFURLRequestSerialization.m
在该类初始化方法 init 的最后,为其几个属性添加了观察者
for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) { if ([self respondsToSelector:NSSelectorFromString(keyPath)]) { [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:AFHTTPRequestSerializerObserverContext]; } }
将观察者设置为自己,观察的属性 keyPath 来自函数 AFHTTPRequestSerializerObservedKeyPaths()
static NSArray * AFHTTPRequestSerializerObservedKeyPaths() { static NSArray *_AFHTTPRequestSerializerObservedKeyPaths = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _AFHTTPRequestSerializerObservedKeyPaths = @[NSStringFromSelector(@selector(allowsCellularAccess)), NSStringFromSelector(@selector(cachePolicy)), NSStringFromSelector(@selector(HTTPShouldHandleCookies)), NSStringFromSelector(@selector(HTTPShouldUsePipelining)), NSStringFromSelector(@selector(networkServiceType)), NSStringFromSelector(@selector(timeoutInterval))]; }); return _AFHTTPRequestSerializerObservedKeyPaths; }
该函数使用了 Objective-C 中典型的单例模式写法,保证数组 _AFHTTPRequestSerializerObservedKeyPaths 只在第一次访问的时候初始化一遍
由于自己是这些属性的观察者,该类也要实现观察者的观察方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(__unused id)object change:(NSDictionary *)change context:(void *)context { if (context == AFHTTPRequestSerializerObserverContext) { if ([change[NSKeyValueChangeNewKey] isEqual:[NSNull null]]) { [self.mutableObservedChangedKeyPaths removeObject:keyPath]; } else { [self.mutableObservedChangedKeyPaths addObject:keyPath]; } } }
该方法在被观察属性改变的时候被调用,用以修改 mutableObservedChangeKeyPaths 属性
最后,在该类对象被回收时,移除观察者
- (void)dealloc { for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) { if ([self respondsToSelector:NSSelectorFromString(keyPath)]) { [self removeObserver:self forKeyPath:keyPath context:AFHTTPRequestSerializerObserverContext]; } } }
标签:类对象 网络 ice sed 初始化 turn null github 路径
原文地址:https://www.cnblogs.com/svens/p/9837411.html