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. InAppDelegate application:didFinishLaunchingWithOptions:
you can do so with the following code:
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
这段话是教怎么用这个类的,在应用启动之后就在AppDelegate application:didFinishLaunchingWithOptions:
方法内调用
By setting
enabled
toYES
forsharedManager
, the network activity indicator will show and hide automatically as requests start and finish. You should not ever need to callincrementActivityCount
ordecrementActivityCount
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手动通知的原因是什么