该文章阅读的AFNetworking的版本为3.2.0。bash
这个类就是控制在网络请求时在状态栏左上角转动的网络活动指示器的显现与隐藏。网络
NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropriate instead.")
复制代码
一上来咱们能够看到有这样一个宏,通过查阅,这个宏的意思是,这个类在扩展中不可用。这个扩展是iOS8的新特性,其余app能够与扩展进行数据交换。app
/**
网络活动指示器是否启用
*/
@property (nonatomic, assign, getter = isEnabled) BOOL enabled;
/**
网络活动指示器是否显示
*/
@property (readonly, nonatomic, assign, getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;
/**
网络活动指示器显示延时,默认是网络请求开始后1秒
*/
@property (nonatomic, assign) NSTimeInterval activationDelay;
/**
网络活动指示器隐藏延时,默认是网络请求结束后0.17秒
*/
@property (nonatomic, assign) NSTimeInterval completionDelay;
复制代码
/**
获取网络活动指示器单例
*/
+ (instancetype)sharedManager;
/**
增长活动的网络请求的数量
*/
- (void)incrementActivityCount;
/**
减小活动的网络请求的数量
*/
- (void)decrementActivityCount;
/**
设置网络活动指示器隐藏和显示时的自定义事件
*/
- (void)setNetworkingActivityActionWithBlock:(nullable void (^)(BOOL networkActivityIndicatorVisible))block;
复制代码
typedef NS_ENUM(NSInteger, AFNetworkActivityManagerState) {
AFNetworkActivityManagerStateNotActive,
AFNetworkActivityManagerStateDelayingStart,
AFNetworkActivityManagerStateActive,
AFNetworkActivityManagerStateDelayingEnd
};
复制代码
这个枚举定义了网络活动指示器的状态:异步
AFNetworkActivityManagerStateNotActive
表示网络活动指示器处于非活动状态 AFNetworkActivityManagerStateDelayingStart
表示网络活动指示器处于延时开始状态 AFNetworkActivityManagerStateActive
表示网络活动指示器处于活动状态 AFNetworkActivityManagerStateDelayingEnd
表示网络活动指示器处于延时结束状态async
/**
定义了开始延时时间,为1秒
*/
static NSTimeInterval const kDefaultAFNetworkActivityManagerActivationDelay = 1.0;
/**
定义告终束延时时间,为0.17秒
*/
static NSTimeInterval const kDefaultAFNetworkActivityManagerCompletionDelay = 0.17;
复制代码
/**
这个方法用户获取通知中的网络请求对象
*/
static NSURLRequest * AFNetworkRequestFromNotification(NSNotification *notification) {
if ([[notification object] respondsToSelector:@selector(originalRequest)]) {
return [(NSURLSessionTask *)[notification object] originalRequest];
} else {
return nil;
}
}
复制代码
/**
定义了网络状态发生变化时的回调block
*/
typedef void (^AFNetworkActivityActionBlock)(BOOL networkActivityIndicatorVisible);
复制代码
/**
活动请求数量
*/
@property (readwrite, nonatomic, assign) NSInteger activityCount;
/**
开始延时计时器
*/
@property (readwrite, nonatomic, strong) NSTimer *activationDelayTimer;
/**
结束延时计时器
*/
@property (readwrite, nonatomic, strong) NSTimer *completionDelayTimer;
/**
是否正在活动状态
*/
@property (readonly, nonatomic, getter = isNetworkActivityOccurring) BOOL networkActivityOccurring;
/**
网络状态发生变化时的回调block
*/
@property (nonatomic, copy) AFNetworkActivityActionBlock networkActivityActionBlock;
/**
当前状态
*/
@property (nonatomic, assign) AFNetworkActivityManagerState currentState;
/**
网络活动指示器是否显示
*/
@property (nonatomic, assign, getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;
复制代码
/**
根据当前的状态改变网络活动指示器的状态
*/
- (void)updateCurrentStateForNetworkActivityChange;
复制代码
+ (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;
// 监听了AFURLSessionManager的三个通知,分别是任务已经开始、任务已经暂停和任务已经结束
[[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;
}
- (void)dealloc {
// 移除对通知的观察
[[NSNotificationCenter defaultCenter] removeObserver:self];
// 结束计时器对象
[_activationDelayTimer invalidate];
[_completionDelayTimer invalidate];
}
复制代码
- (void)setEnabled:(BOOL)enabled {
_enabled = enabled;
// 若是设置为NO,就把网络活动指示器的状态设置为非活动状态
if (enabled == NO) {
[self setCurrentState:AFNetworkActivityManagerStateNotActive];
}
}
- (void)setNetworkingActivityActionWithBlock:(void (^)(BOOL networkActivityIndicatorVisible))block {
// 记录传入的block
self.networkActivityActionBlock = block;
}
- (BOOL)isNetworkActivityOccurring {
// 加锁获取网络请求数量,大于0就是正在活动状态
@synchronized(self) {
return self.activityCount > 0;
}
}
- (void)setNetworkActivityIndicatorVisible:(BOOL)networkActivityIndicatorVisible {
// 若是新老数据不一致
if (_networkActivityIndicatorVisible != networkActivityIndicatorVisible) {
// 手动实现networkActivityIndicatorVisible属性的KVO方法
[self willChangeValueForKey:@"networkActivityIndicatorVisible"];
// 加锁赋值
@synchronized(self) {
_networkActivityIndicatorVisible = networkActivityIndicatorVisible;
}
[self didChangeValueForKey:@"networkActivityIndicatorVisible"];
if (self.networkActivityActionBlock) {
// 若是设置了回调block就调用
self.networkActivityActionBlock(networkActivityIndicatorVisible);
} else {
// 若是没有设置回调block就直接设置网络活动指示器的显示状态
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:networkActivityIndicatorVisible];
}
}
}
- (void)setActivityCount:(NSInteger)activityCount {
// 加锁赋值
@synchronized(self) {
_activityCount = activityCount;
}
// 主队列异步调用
dispatch_async(dispatch_get_main_queue(), ^{
// 更新当前网络状态
[self updateCurrentStateForNetworkActivityChange];
});
}
- (void)incrementActivityCount {
// 手动实现activityCount属性的KVO方法
[self willChangeValueForKey:@"activityCount"];
// 加锁赋值
@synchronized(self) {
_activityCount++;
}
[self didChangeValueForKey:@"activityCount"];
// 主队列异步调用更新当前网络状态
dispatch_async(dispatch_get_main_queue(), ^{
[self updateCurrentStateForNetworkActivityChange];
});
}
- (void)decrementActivityCount {
// 手动实现activityCount属性的KVO方法
[self willChangeValueForKey:@"activityCount"];
// 加锁赋值
@synchronized(self) {
// 不能小于零
_activityCount = MAX(_activityCount - 1, 0);
}
[self didChangeValueForKey:@"activityCount"];
// 主队列异步调用更新当前网络状态
dispatch_async(dispatch_get_main_queue(), ^{
[self updateCurrentStateForNetworkActivityChange];
});
}
复制代码
- (void)networkRequestDidStart:(NSNotification *)notification {
// 接收到任务开始的通知若是请求对象中有URL就增长请求活动数量
if ([AFNetworkRequestFromNotification(notification) URL]) {
[self incrementActivityCount];
}
}
- (void)networkRequestDidFinish:(NSNotification *)notification {
// 接收到任务结束的通知若是请求对象中有URL就减小请求活动数量
if ([AFNetworkRequestFromNotification(notification) URL]) {
[self decrementActivityCount];
}
}
- (void)setCurrentState:(AFNetworkActivityManagerState)currentState {
// 加锁保护
@synchronized(self) {
// 若是新老数据不一致
if (_currentState != currentState) {
// 手动实现currentState属性的KVO方法
[self willChangeValueForKey:@"currentState"];
// 赋值
_currentState = currentState;
switch (currentState) {
// 若是设置的是无活动
case AFNetworkActivityManagerStateNotActive:
// 取消开始和完成延时计时器
[self cancelActivationDelayTimer];
[self cancelCompletionDelayTimer];
// 隐藏网络活动指示器
[self setNetworkActivityIndicatorVisible:NO];
break;
// 若是设置的是延时开始
case AFNetworkActivityManagerStateDelayingStart:
// 开始开始延时计时
[self startActivationDelayTimer];
break;
// 若是设置的是开始
case AFNetworkActivityManagerStateActive:
// 取消完成延时计时器
[self cancelCompletionDelayTimer];
// 显示网络活动指示器
[self setNetworkActivityIndicatorVisible:YES];
break;
// 若是设置的是延时结束
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;
}
}
}
- (void)startActivationDelayTimer {
// 设置开始延时计时器并加入到运行循环中
self.activationDelayTimer = [NSTimer
timerWithTimeInterval:self.activationDelay target:self selector:@selector(activationDelayTimerFired) userInfo:nil repeats:NO];
[[NSRunLoop mainRunLoop] addTimer:self.activationDelayTimer forMode:NSRunLoopCommonModes];
}
- (void)activationDelayTimerFired {
// 若是当前有网络活动
if (self.networkActivityOccurring) {
// 就设置状态为活动
[self setCurrentState:AFNetworkActivityManagerStateActive];
// 若是当前无网络活动
} else {
// 就设置状态为非活动
[self setCurrentState:AFNetworkActivityManagerStateNotActive];
}
}
- (void)startCompletionDelayTimer {
// 先使以前的计时器无效
[self.completionDelayTimer invalidate];
// 设置结束延时计时器并加入到运行循环中
self.completionDelayTimer = [NSTimer timerWithTimeInterval:self.completionDelay target:self selector:@selector(completionDelayTimerFired) userInfo:nil repeats:NO];
[[NSRunLoop mainRunLoop] addTimer:self.completionDelayTimer forMode:NSRunLoopCommonModes];
}
- (void)completionDelayTimerFired {
// 设置状态为非活动
[self setCurrentState:AFNetworkActivityManagerStateNotActive];
}
- (void)cancelActivationDelayTimer {
// 使开始延时计时器无效
[self.activationDelayTimer invalidate];
}
- (void)cancelCompletionDelayTimer {
// 使完成延时计时器无效
[self.completionDelayTimer invalidate];
}
复制代码
看完了代码,咱们能够梳理一下AFNetworkActivityIndicatorManager
类的工做流程:oop
1.经过在初始化方法中注册通知监听AFNetworking
的task
的开始、暂停和结束。post
2.当接收到task
开始的通知时,就会在通知的回调方法中记录当前网络请求活动数量,手动发送KOV,而后调用更新状态方法。ui
3.在更新状态方法中,若是当前的状态是非活动,而且有网络请求活动,就会将当前状态设置为延时开始状态。atom
4.在currentState
属性的setter中,先手动发送KVO,若是发现设置的状态为开始延时状态,就会开启开始延时计时器。spa
5.在1秒事后就会触发计时器方法,在计时器方法中,若是发现当前依然有网络请求在进行中,就将当前状态设置为活动状态。可是若是当前已经没有进行中的网络请求了,就会把状态设置为非活动状态。
6.这时就又回到了重写的currentState
属性的setter中,依旧是先手动发送KVO,若是发现设置的状态为开始状态,就结束掉完成延时计时器,并显示网络活动指示器。
7.当接收到task
结束的通知时,一样的会在通知的回调方法中记录当前网络请求活动数量,手动发送KOV,而后调用更新状态方法。
8.在更新状态方法中,若是当前的状态是活动,而且已经没有进行中的网络请求了,就会将当前状态设置为延时结束状态。
9.在重写的currentState
属性setter中,除了手动发送KVO,若是发现设置的状态为延时结束状态,就会开启完成延时计时器。
10.在0.17秒事后,触发计时器方法,计时器方法中会将状态设置为非活动状态,在currentState
的setter中,先手动发送KVO,在非活动状态下就会结束掉开始和完成延时计时器,并隐藏网络活动指示器
源码阅读系列:AFNetworking
源码阅读:AFNetworking(二)——AFURLRequestSerialization
源码阅读:AFNetworking(三)——AFURLResponseSerialization
源码阅读:AFNetworking(四)——AFSecurityPolicy
源码阅读:AFNetworking(五)——AFNetworkReachabilityManager
源码阅读:AFNetworking(六)——AFURLSessionManager
源码阅读:AFNetworking(七)——AFHTTPSessionManager
源码阅读:AFNetworking(八)——AFAutoPurgingImageCache
源码阅读:AFNetworking(九)——AFImageDownloader
源码阅读:AFNetworking(十)——AFNetworkActivityIndicatorManager
源码阅读:AFNetworking(十一)——UIActivityIndicatorView+AFNetworking
源码阅读:AFNetworking(十二)——UIButton+AFNetworking
源码阅读:AFNetworking(十三)——UIImageView+AFNetworking
源码阅读:AFNetworking(十四)——UIProgressView+AFNetworking