三、Reachability部分
Reachability是用来检测网络连接状态的,主要功能由AFNetworkReachabilityManager类来实现。下面就来具体分析一下AFNetworkReachabilityManager类的源码。由于这个类功能比较单一,所以代码量相对于其他部分也更为简洁。
同样,下面通过一个调用使用来分析其工作原理:
由注解可看出其是基于系统的Reachability实现。可以用来定位后台网络连接失败的信息,或是用来重启一个请求。但是不能用来阻止一个已经发起的请求。
现在开始分析具体代码,先看一下工具类的初始化:
看到第一步是初始化一个系统的sockaddr_in类型的地址,并指明address.sin_family=AF_INET其家族地址协议簇为TCP/IP协议类型。参见详情
继续深入:
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)address)通过前一步传入的地址来测试连接状态,reachability用来保存创建测试连接返回的引用。在接下来的- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability方法中保存这个引用_networkReachability = CFRetain(reachability)并设置初始值self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown。参看详情
就此工具类的初始化完成,接着分析调用[manager startMonitoring]:
可看到在每次进入监视时,如果之前设置过监听,都先停止之前的监视[self stopMonitoring]
看到stopMonitoring是调用SCNetworkReachabilityUnscheduleFromRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes)这个系统方法实现的。
紧接着
设置网络状态变化时的回调,可看出每次网络状态变化时将重新设置网络状态strongSelf.networkReachabilityStatus = status并调用strongSelf.networkReachabilityStatusBlock(status)。
紧接着创建网络状态监控上下文
设置context的info为callback,AFNetworkReachabilityRetainCallback和AFNetworkReachabilityReleaseCallback只是对传入的info进行引用计数管理。
接着调用系统方法设置网络状态变化时调用的block
当网络状态发生变化时,将调用AFNetworkReachabilityCallback进而调用AFPostReachabilityStatusChange再调用之前传进去的开发者设置的AFNetworkReachabilityStatusBlock类型回调。
看看AFPostReachabilityStatusChange中是通过AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags)这个方法获取状态的:
这个方法可看出flag是系统返回的网络状态,这个函数主要是将系统提供的复杂的状态转化为对应的框架提供的简洁的状态。
在main runloop模式中开始监控网络状态
接着获取当前的网络状态并回调
这就是[manager startMonitoring]中所做的事。
紧接着这一步
也就是设置网络状态变化时要调用的block。
最后调用[manager stopMonitoring],之前分析过。
就此一次对Reachability的使用结束。
纵观源码可看出AFNetworkReachabilityManager其实是对系统自带的c语言的SCNetworkReachability的一个OC语言的封装,提供了OC简便使用的接口。