码迷,mamicode.com
首页 > Web开发 > 详细

AFNetworking 中观察者模式解析

时间:2018-10-23 21:12:21      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:类对象   网络   ice   sed   初始化   turn   null   github   路径   

0. Objective-C 中的观察者模式(KVO)

Objective-C 语言实现了观察者模式(Key Value Observing, KVO),并提供了简单的使用接口。

供给使用者方便的注册观察者,注册观察方法,移除观察者。

a. 注册观察者

/* 
方法的接收者 objectA 是被观察者 objectB 观察的对象
方法的第一个参数 objectB 是注册到 objectA 上的观察者
方法的第二个参数 @”property“ 是被观察者 objectB 监听的属性,当该属性发生改变时,通知观察者做出反应
options: 有4个值,分别是:
NSKeyValueObservingOptionOld 把更改之前的值提供给处理方法 
NSKeyValueObservingOptionNew 把更改之后的值提供给处理方法 
NSKeyValueObservingOptionInitial 把初始化的值提供给处理方法,一旦注册,立马就会调用一次。通常它会带有新值,而不会带有旧值。 
NSKeyValueObservingOptionPrior 分2次调用。在值改变之前和值改变之后。 
 */
[objectA addObserver:objectB forKeyPath:@"property" options:NSKeyValueObservingOptionNew context:nil];

b. 实现观察者的观察方法

在观察者 objectB 的实现文件中添加观察方法

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary<NSKeyValueChangeKey,id> *)change
                       context:(void *)contex
    // 在这里添加处理改变的逻辑            
}

c. 移除观察者

//删除指定的key路径监听器
[self.person removeObserver:self forKeyPath:@"name"];
//删除指定的key路径监听器,只是多了context参数
[self.person removeObserver:self forKeyPath:@"name" context:nil];

1. 什么是 AFNetworking ?

AFNetworking 是 iOS 开发中使用最多的第三方网络库,封装了 iOS 原生网络请求。

其中使用了大量 KVO 来对属性改变做出反应。

2. 通过 AFHTTPRequestSerialization 类来说明观察者模式

代码地址 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];
        }
    }
}

 

AFNetworking 中观察者模式解析

标签:类对象   网络   ice   sed   初始化   turn   null   github   路径   

原文地址:https://www.cnblogs.com/svens/p/9837411.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!