源码分析之AFNetworking ②AFNetworkReachabilityManager

Posted 梦想家-mxj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了源码分析之AFNetworking ②AFNetworkReachabilityManager相关的知识,希望对你有一定的参考价值。

AFNetworkReachabilityManager对象用于监听设备当前连接网络的状态。
AFNetworkReachabilityManager提供了4种创建方法:

  • (instancetype)sharedManager; //创建单例

  • (instancetype)manager;//创建实例对象

  • (instancetype)managerForDomain:(NSString *)domain;//根据地址名创建实例对象

  • (instancetype)managerForAddress:(const void *)address;//根据sockaddr创建实例对象

  • (instancetype)sharedManager {
    static AFNetworkReachabilityManager *_sharedManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    _sharedManager = [self manager];
    });

    return _sharedManager;
    }
    shareManager调用manager方法创建一个AFNetworkReachabilityManager对象

通过枚举值查看网络状态
typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
AFNetworkReachabilityStatusUnknown = -1,
AFNetworkReachabilityStatusNotReachable = 0,//未连接
AFNetworkReachabilityStatusReachableViaWWAN = 1,//蜂窝
AFNetworkReachabilityStatusReachableViaWiFi = 2,//wifi
};
网络监听
AFNetworkReachabilityManager通过startMonitoring和stopMonitoring方法来开始和停止监听当前设备连接的网络状态

  • (void)startMonitoring {
    [self stopMonitoring];

    if (!self.networkReachability) {
    return;
    }

    __weak __typeof(self)weakSelf = self;
    AFNetworkReachabilityStatusCallback callback = ^(AFNetworkReachabilityStatus status) {
    __strong __typeof(weakSelf)strongSelf = weakSelf;

      strongSelf.networkReachabilityStatus = status;
      if (strongSelf.networkReachabilityStatusBlock) {
          strongSelf.networkReachabilityStatusBlock(status);
      }
      
      return strongSelf;
    

    };

    SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL};
    SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback, &context);
    SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{
    SCNetworkReachabilityFlags flags;
    if (SCNetworkReachabilityGetFlags(self.networkReachability, &flags)) {
    AFPostReachabilityStatusChange(flags, callback);
    }
    });
    }
    startMonitoring方法中首先调用stopMonitoring方法,即先停止之前的监听,然后调用SCNetworkReachabilitySetCallback方法设置networkReachability的回调函数、AFNetworkReachabilityCallback和上下文context对象
    另外AFPostReachabilityStatusChange的实现
    static void AFPostReachabilityStatusChange(SCNetworkReachabilityFlags flags, AFNetworkReachabilityStatusCallback block) {
    AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags);//根据flags获取当前网络连接状态status
    dispatch_async(dispatch_get_main_queue(), ^{
    AFNetworkReachabilityManager *manager = nil;
    if (block) {
    manager = block(status);
    }
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    NSDictionary *userInfo = @{ AFNetworkingReachabilityNotificationStatusItem: @(status) };
    [notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:manager userInfo:userInfo];
    });
    }
    此方法首先根据系统回调的AFNetworkReachabilityStatusForFlags方法以及falgs参数,获取网络连接状态,然后进入block,将status抛出外界,同时抛一个通知将status抛给外界,当网络状态发生改变,会同事用这两种方式传递给外界。
    AFNetworkReachabilityStatusForFlags方法是核心方法,负责根据flag的状态值,转化为相应的枚举值AFNetworkReachabilityStatus。

  • (void)stopMonitoring {
    if (!self.networkReachability) {
    return;
    }
    SCNetworkReachabilityUnscheduleFromRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
    }
    该方法通过监听的方法让networkReachability对象从runloop中注销。

//监听网络状态的demo

[[AFNetworkReachabilityManager sharedManager] startMonitoring];
    [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        switch (status) {
            case AFNetworkReachabilityStatusUnknown:
                NSLog(@"未知");
                break;
            case AFNetworkReachabilityStatusNotReachable:
                NSLog(@"未连接");
                break;
            case AFNetworkReachabilityStatusReachableViaWWAN:
                NSLog(@"移动");
                break;
            case AFNetworkReachabilityStatusReachableViaWiFi:
                NSLog(@"WiFi");
                break;
            default:
                break;
        }
    }];

以上是关于源码分析之AFNetworking ②AFNetworkReachabilityManager的主要内容,如果未能解决你的问题,请参考以下文章

源码分析之AFNetworking ②AFNetworkReachabilityManager

源码分析之AFNetworking④UIkit+AFNetworking

源码分析之AFNetworking④UIkit+AFNetworking

源码分析之AFNetworking④UIkit+AFNetworking

源码分析之AFNetworking④UIkit+AFNetworking

源码分析之AFNetworking③AFSecurityPolicy和AFURLRequestSerialization