AFNetworking 3.x 阅读笔记(一)

大概在两个月以前阅读了AFN的2.x的源代码,因为项目中一直使用的2.x,这几天抽空把3.x的代码补上.第一篇笔记记录AFN的demo,有了demo就知道如何用这个库,能够掌握业务知识,然后再深入学习底层的源码,能够站在不一样的角度去看待一些问题.

Delegate中的内容

首先在AppDelegate中有如下代码,其中NSURLCacheAFNetworkActivityIndicatorManager两个类需要学习

NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];
    
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES]; 

NSURLCache

NSURLCache 中提到NSURLCache 为您的应用的 URL 请求提供了内存中以及磁盘上的综合缓存机制. 作为基础类库 URL 加载系统 的一部分,任何通过 NSURLConnection/NSURLSession加载的请求都将被 NSURLCache 处理.当一个请求完成下载来自服务器的回应,一个缓存的回应将在本地保存。下一次同一个请求再发起时,本地保存的回应就会马上返回,不需要连接服务器。NSURLCache会自动且透明地返回响应,具体的缓存策略由客户端和服务端共同协商搞定.

在我们发出的请求NSURLRequest中会有一个cachePolicy属性,它就是客户端在发出请求时设定的缓存策略.具体有几种模式,可以参考官方文档,以下表格表示实际中常用的几个策略以及其真实含义:

枚举 含义
UseProtocolCachePolicy 默认行为
ReloadIgnoringLocalCacheData 不使用缓存
ReturnCacheDataElseLoad 使用缓存(不管它是否过期)如果缓存中没有,就从网络加载
ReturnCacheDataDontLoad 离线模式:使用缓存(不管它是否过期),但是不从网络加载

AFNetworkActivityIndicatorManager维护的状态机

这个类是AFN的中监听网络状态的类.主要根据当前是否有请求管理status bar上的activity indicator的显示与关闭.

AFNetworkActivityIndicatorManager会维护一个状态机,记录当前网络框架中是否有请求,并通过activityCount属性维护当前同时的session请求的个数来决定是否在status bar显示菊花.

typedef NS_ENUM(NSInteger, AFNetworkActivityManagerState) {
    AFNetworkActivityManagerStateNotActive,
    AFNetworkActivityManagerStateDelayingStart,
    AFNetworkActivityManagerStateActive,
    AFNetworkActivityManagerStateDelayingEnd
};

Demo中给了一个很好的示例,在app启动完成以后直接调用[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES]监听菊花的控制,默认情况下并未监听.

状态机的核心方法如下:

#pragma mark - Internal State Management
- (void)setCurrentState:(AFNetworkActivityManagerState)currentState {
    @synchronized(self) {//设置状态需要加锁
        if (_currentState != currentState) {
            [self willChangeValueForKey:@"currentState"];
            _currentState = currentState;
            switch (currentState) {
                //初始化状态,需要重置重要参数的状态
                case AFNetworkActivityManagerStateNotActive:
                    [self cancelActivationDelayTimer];
                    [self cancelCompletionDelayTimer];
                    [self setNetworkActivityIndicatorVisible:NO];
                    break;
                //转换成delay开始状态->这里有个延迟显示的问题
                case AFNetworkActivityManagerStateDelayingStart:
                    [self startActivationDelayTimer];
                    break;
                //转换成正在active状态,菊花可见
                case AFNetworkActivityManagerStateActive:
                    [self cancelCompletionDelayTimer];
                    [self setNetworkActivityIndicatorVisible:YES];
                    break;
                //转换成delay结束状态->delay time以后状态会被设置成NotActive
                case AFNetworkActivityManagerStateDelayingEnd:
                    [self startCompletionDelayTimer];
                    break;
            }
            [self didChangeValueForKey:@"currentState"];
        }
    }
}

- (void)updateCurrentStateForNetworkActivityChange {
    if (self.enabled) {
        switch (self.currentState) {
            case AFNetworkActivityManagerStateNotActive:
                if (self.isNetworkActivityOccurring) {
                    [self setCurrentState:AFNetworkActivityManagerStateDelayingStart];
                }
                break;
            case AFNetworkActivityManagerStateDelayingStart:
                //No op. Let the delay timer finish out.
                break;
            case AFNetworkActivityManagerStateActive:
                if (!self.isNetworkActivityOccurring) {
                    [self setCurrentState:AFNetworkActivityManagerStateDelayingEnd];
                }
                break;
            case AFNetworkActivityManagerStateDelayingEnd:
                if (self.isNetworkActivityOccurring) {
                    [self setCurrentState:AFNetworkActivityManagerStateActive];
                }
                break;
        }
    }
}

在监听广播收到AFNetworkingTaskDidResumeNotification,AFNetworkingTaskDidSuspendNotification,AFNetworkingTaskDidResumeNotification等Notification时,就会调用incrementActivityCount,decrementActivityCount方法对_activityCount进行改变并且调用updateCurrentStateForNetworkActivityChange方法改变状态.

其他值得学习的地方

timer使用commomMode

将timer加到NSRunLoopCommonModes中可以在任何时候都能保证timer的运行

[[NSRunLoop mainRunLoop] addTimer:self.activationDelayTimer forMode:NSRunLoopCommonModes];

.h使用readonly,.m可以修改

该类中有属性networkActivityIndicatorVisible,如果需要外部访问是readonly而内部可以修改.可以参考下面做法:

// .h中
@property (readonly, nonatomic, assign, getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;

//.m中
@property (nonatomic, assign, getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;

AFNetworking中的几个通知

也许在其他地方也用得着这几个通知

AFNetworkingTaskDidResumeNotification
AFNetworkingTaskDidSuspendNotification
AFNetworkingTaskDidCompleteNotification

在demo中调用了[self.refreshControl setRefreshingWithStateOfTask:task]这样一个方法.通过源码可以发现正式用了这几个通知控制refresh的开始和停止刷新.

- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task {
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];

    [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil];
    [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil];
    [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil];

    if (task) {
        UIRefreshControl *refreshControl = self.refreshControl;
        if (task.state == NSURLSessionTaskStateRunning) {
            [refreshControl beginRefreshing];

            [notificationCenter addObserver:self selector:@selector(af_beginRefreshing) name:AFNetworkingTaskDidResumeNotification object:task];
            [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidCompleteNotification object:task];
            [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidSuspendNotification object:task];
        } else {
            [refreshControl endRefreshing];
        }
    }
}

你可能感兴趣的:(AFNetworking 3.x 阅读笔记(一))