iOS学习----------AFNetworking(1)网络监控

名次解释
1、AFNetworking:AFNetworking是一款在OS X和iOS下都令人喜爱的网络库
github地址:https://github.com/AFNetworking/AFNetworking.git

2、我们从最常用的监控网络请求开始
这时是创建单例的流程
这里写图片描述
1、创建单例

+ (instancetype)managerForAddress:(const void *)address {
    //创建了id类型的reachability
    //reachability表示的是需要检测的网络地址的句柄
    //通过SCNetworkReachabilityCreateWithAddress函数创建句柄
    SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)address);
    AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability];

    return manager;
}

2、初始化操作


- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability {
    self = [super init];
    if (!self) {
        return nil;
    }
    //保存监控网络的句柄
    self.networkReachability = CFBridgingRelease(reachability);
    //设置初始网络状态
    self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown;

    return self;
}

3、调用startMonitoring方法开始网络监控
(1)先调用stopMonitoring方法将当前监控网络请求的句柄从runloop中移除

- (void)stopMonitoring {
    if (!self.networkReachability) {
        return;
    }

    //将句柄为networkReachability 从runloop中移除
    SCNetworkReachabilityUnscheduleFromRunLoop((__bridge SCNetworkReachabilityRef)self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
}

(2)根据当前的网络状态来设置回调函数callback

    __weak __typeof(self)weakSelf = self;
    // 根据网络状态status来设置网络状态监听的回调函数callback
    AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
        __strong __typeof(weakSelf)strongSelf = weakSelf;

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

    };

(3)创建SCNetworkReachabilityContext类型的上下文结构体

   /** context是一个结构体
         typedef struct {
         // 创建一个SCNetworkReachabilityContext结构体时,需要调用SCDynamicStore的创建函数,而此创建函数会根据version来创建出不同的结构体,SCNetworkReachabilityContext对应的version是0
         CFIndex        version;

         // 下面两个block(release和retain)的参数就是info,此处表示的是网络状态处理的回调函数
         void *        __nullable info;

         // 该retain block用于对info进行retain,下面那个AFNetworkReachabilityRetainCallback核心就是调用了Block_copy(用于retain一个block函数,即在堆空间新建或直接引用一个block拷贝)
         const void    * __nonnull (* __nullable retain)(const void *info);
         // 该release block用于对info进行release,下面那个AFNetworkReachabilityReleaseCallback核心就是调用了Block_release(用于release一个block函数,即将block从堆空间移除或移除相应引用)
         void        (* __nullable release)(const void *info);
         // 提供info的description,此处调用为NULL
         CFStringRef    __nonnull (* __nullable copyDescription)(const void *info);
         } SCNetworkReachabilityContext;
     */


    SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL};

version:// 创建一个SCNetworkReachabilityContext结构体时,需要调用SCDynamicStore的创建函数,而此创建函数会根据version来创建出不同的结构体,SCNetworkReachabilityContext对应的version是0
info:下面两个block(release和retain)的参数就是info,此处表示的是网络状态处理的回调函数
retain:该retain block用于对info进行retain,下面那个AFNetworkReachabilityRetainCallback核心就是调用了Block_copy(用于retain一个block函数,即在堆空间新建或直接引用一个block拷贝)const void * __nonnull (* __nullable retain)(const void *info);
release:该release block用于对info进行release,下面那个AFNetworkReachabilityReleaseCallback核心就是调用了Block_release(用于release一个block函数,即将block从堆空间移除或移除相应引用)
copyDescription: 提供info的description,此处调用为NULL

(4)给客户端指定对应target(该参数和需要检测网络状况的地址有一定关联,此处使用的是self.networkReachability),然后当这个target的网络状态变化时,告之SCNetworkReachabilityCallBack对象callout处理(此处使用的是AFNetworkReachabilityCallback),另外callout中使用到的参数包括target和context提供的info。

/*
  Boolean
     SCNetworkReachabilitySetCallback    (
     SCNetworkReachabilityRef                                        target,
     SCNetworkReachabilityCallBack    __nullable    callout,
     SCNetworkReachabilityContext    * __nullable    context
     )                __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_2_0);
     */

    SCNetworkReachabilitySetCallback((__bridge SCNetworkReachabilityRef)networkReachability, AFNetworkReachabilityCallback, &context);

(5)将该监控加入到runloop 中 此方法与stopMonitoring相对应

//    此处表示在main RunLoop中以kCFRunLoopCommonModes形式处理self.networkingReachability
    SCNetworkReachabilityScheduleWithRunLoop((__bridge SCNetworkReachabilityRef)networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);

(6)在后台检测self.networkReachability的网络状态,并使用SCNetworkReachabilityGetFlags函数返回产生的flag,注意此处flag表示的就是网络的状态

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{
        SCNetworkReachabilityFlags flags;
        if (SCNetworkReachabilityGetFlags((__bridge SCNetworkReachabilityRef)networkReachability, &flags)) {
            AFPostReachabilityStatusChange(flags, callback);
        }
    });

(7)AFPostReachabilityStatusChange当网络状态发生改变的时候使用该方法发送通知,通知用户目前的网络状态。通过userInfo[AFNetworkingReachabilityNotificationStatusItem]获取到相应的status

static void AFPostReachabilityStatusChange(SCNetworkReachabilityFlags flags, AFNetworkReachabilityStatusBlock block) {

    // 使用AFNetworkReachabilityStatusForFlags函数将flags转化为status,提供给下面block使用
    AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags);
    dispatch_async(dispatch_get_main_queue(), ^{
        if (block) {
            block(status);
        }

        // 对于用户,可以使用KVO来观察status的变化,随后用户可以根据传过来的userInfo[AFNetworkingReachabilityNotificationStatusItem]获取到相应的status
        NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
        NSDictionary *userInfo = @{ AFNetworkingReachabilityNotificationStatusItem: @(status) };
        [notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:userInfo];
    });
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值