美文网首页iOSiOS第三方库
AFNetworking 3.x 阅读笔记(一)

AFNetworking 3.x 阅读笔记(一)

作者: brownfeng | 来源:发表于2016-09-17 23:43 被阅读175次

    大概在两个月以前阅读了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 阅读笔记(一)

        本文链接:https://www.haomeiwen.com/subject/moxqjttx.html