AFNetworking源码阅读(一)

1.示范文档

首先看iOS Example

打开Appdelegate文件

第一行代码是


NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];

[NSURLCache setSharedURLCache:URLCache];

这个缓存类以前没有注意过,也没有用过,打开帮助文档看看

Description:
Initializes an NSURLCache object with the specified values.(初始化一个NSURLCache实例)

Parameters:(参数)
memoryCapacity:The memory capacity of the cache, in bytes.
(内存缓存的容量:单位为bytes)
diskCapacity:The disk capacity of the cache, in bytes.
(硬盘缓存的容量:单位为bytes)
path:In OS X, path is the location at which to store the on-disk cache.
In iOS, path is the name of a subdirectory of the application’s default cache directory in which to store the on-disk cache (the subdirectory is created if it does not exist).
OS X存储路径在硬盘 cache文件夹
iOS:在应用的默认cache文件夹子目录下,如果子目录不存在时会创建一个新的
创建了网络缓存实例,内存缓存4M, 硬盘缓存为20M,路径为默认nil

这个日后再深入研究吧,不知道内存、硬盘都满了会发生什么情况

再看下面一句

[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];

属于UIKit+AFNetworking里面的类
点进去发现注释非常详细,都是英文,慢慢啃吧

AFNetworkActivityIndicatorManager manages the state of the network activity indicator in the status bar. When enabled, it will listen for notifications indicating that a session task has started or finished, and start or stop animating the indicator accordingly. The number of active requests is incremented and decremented much like a stack or a semaphore, and the activity indicator will animate so long as that number is greater than zero.
AFNetworkActivityIndicatorManager类是管理状态栏上的网络指示器,就是那个会转的小菊花。当设置enabled属性为YES,它会接受session task(会话层任务?)的通知,当任务结束、开始或则指示器会相应地以动画的形式开始转或者消失,如果网络任务请求数量大于零,指示器将会持续转一段时间

You should enable the shared instance of AFNetworkActivityIndicatorManager when your application finishes launching. In AppDelegate application:didFinishLaunchingWithOptions: you can do so with the following code:

[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
这段话是教怎么用这个类的,在应用启动之后就在AppDelegate application:didFinishLaunchingWithOptions:方法内调用

By setting enabled to YES for sharedManager, the network activity indicator will show and hide automatically as requests start and finish. You should not ever need to call incrementActivityCount or decrementActivityCount yourself.
只要设置enabled属性为YES,这个类就会自动处理指示器出现和消失,不需要调用incrementActivityCount和decrementActivityCount这两个参数

NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropriate instead.")
iOS8新特性,扩展,Today视图之类的,不能在扩展中使用
@property (nonatomic, assign) NSTimeInterval activationDelay;
这个参数有点意思,按照苹果人机交互原则,如果网络请求过快就不需要显示菊花转,默认值为1秒,这个参数猜测应该是少于1秒的请求就不显菊花,接下来在实现文件中再研究
@property (nonatomic, assign) NSTimeInterval completionDelay;
和activationDelay相对应,如果有多个请求,指示器为了连贯,会有一个延迟消失的时间,默认为0.17秒
- (void)setNetworkingActivityActionWithBlock:(nullable void (^)(BOOL networkActivityIndicatorVisible))block;
这个方法在指示器即将出现、消失时调用,调用这个方法可以通过block自定义某些逻辑,默认是null,manager会自动管理指示器的出现,消失,如果设置了block,需要手动管理,其实就是调用系统的方法:[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:networkActivityIndicatorVisible];
NS_ASSUME_NONNULL_BEGIN

NS_ASSUME_NONNULL_END
苹果为了和swift的可选类型兼容设定的宏,用了这两个宏,它们中间的方法参数默认为__nonnull,只需要为特定的参数设置__nullable就可以了

实现文件:

typedef NS_ENUM(NSInteger, AFNetworkActivityManagerState) {
    AFNetworkActivityManagerStateNotActive,
    AFNetworkActivityManagerStateDelayingStart,
    AFNetworkActivityManagerStateActive,
    AFNetworkActivityManagerStateDelayingEnd
};
static NSTimeInterval const kDefaultAFNetworkActivityManagerActivationDelay = 1.0;
static NSTimeInterval const kDefaultAFNetworkActivityManagerCompletionDelay = 0.17;
按照OC规范定义了四个枚举和两个常量,之前所说的按照apple人机交互原则设定
+ (instancetype)sharedManager {
    static AFNetworkActivityIndicatorManager *_sharedManager = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _sharedManager = [[self alloc] init];
    });

    return _sharedManager;
}
标准的单例写法

接下来主要探讨一下网络请求多任务下指示器的工作

- (instancetype)init {
    self = [super init];
    if (!self) {
        return nil;
    }
    self.currentState = AFNetworkActivityManagerStateNotActive;
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidStart:) name:AFNetworkingTaskDidResumeNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingTaskDidSuspendNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingTaskDidCompleteNotification object:nil];
    self.activationDelay = kDefaultAFNetworkActivityManagerActivationDelay;
    self.completionDelay = kDefaultAFNetworkActivityManagerCompletionDelay;

    return self;
}
首先在初始化方法里设置了三个通知,通过currentState来控制指示器的状态

看一下请求开始的时候通知方法

1.在networkRequestDidStart:方法接收通知,验证请求地址,activityCount+1

2.主线程下更新currentState,设置开始延时定时器[self startActivationDelayTimer],定时器加入到NSRunLoopCommonModes的runloop

3.定时器到时方法activationDelayTimerFired,通过networkActivityOccurring(activityCount是否 > 0)属性判断CurrentState状态,如果activityCount>0,把currentState设置为AFNetworkActivityManagerStateActive

4.最后通过setNetworkActivityIndicatorVisible方法展现指示器

请求结束的通知方法:

1.networkRequestDidFinish:方法接收通知,验证请求地址,activityCount-1,当activityCount == 0,状态会有所变化
2.主线程下更新CurrentState,设置结束延时定时器[self startCompletionDelayTimer],定时器加入到NSRunLoopCommonModes的runloop
3.定时器到时方法completionDelayTimerFired,调用[self setCurrentState:AFNetworkActivityManagerStateNotActive];设置currentState为无活动
4.关闭定时器
[self cancelActivationDelayTimer]; [self cancelCompletionDelayTimer];
调用setNetworkActivityIndicatorVisible:方法使指示器菊花消失

指示器实现方法大概就是这样了,顺带说一下,session task通知是由AFURLSessionManager类发出的异步通知

还有就是有一点不明白的地方,AFN使用了很多KVO手动通知

比如说:

[self willChangeValueForKey:@"networkActivityIndicatorVisible"];
[self didChangeValueForKey:@"networkActivityIndicatorVisible"];

这一对,但是没有看见设置了观察者和关闭自动通知的方法。不知道设置kvo手动通知的原因是什么

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,563评论 18 139
  • 一直使用AFNetworking却从不知道是怎么实现的,这次心血来潮,想看看大牛们是怎么写代码的。 看了一下...
    小沫360阅读 828评论 0 1
  • 想了想,转眼之间我又后悔了。我这么大好的一个姑娘凭什么浪费时间浪费精力去回首往事呢?在感情的世界里,时间是说明不了...
    凌冰阅读 205评论 0 1
  • 心若枯竭,余者皆为荒漠,可叹身处其中而不自知,一路向前,不知为何,走走停停,不曾驻足,何来热爱。 原来痛苦不被感知...
    卷耳薛阅读 222评论 0 1