AFNetworking2.0源码解析<一>

本文详细解析AFNetworking2的核心类AFURLConnectionOperation,从代码层面深入探讨其实现细节,包括线程管理、状态切换及单例生成等关键点,并通过实例演示如何正确使用该类构建网络请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近看AFNetworking2的源码,学习这个知名网络框架的实现,顺便梳理写下文章。AFNetworking2的大体架构和思路在这篇文章已经说得挺清楚了,就不再赘述了,只说说实现的细节。AFNetworking的代码还在不断更新中,我看的是AFNetworking2.3.1

本篇先看看AFURLConnectionOperation,AFURLConnectionOperation继承自NSOperation,是一个封装好的任务单元,在这里构建了NSURLConnection,作为NSURLConnection的delegate处理请求回调,做好状态切换,线程管理,可以说是AFNetworking最核心的类,下面分几部分说下看源码时注意的点,最后放上代码的注释。

0.Tricks

AFNetworking代码中有一些常用技巧,先说明一下。

A.clang warning
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
//code
#pragma clang diagnostic pop

表示在这个区间里忽略一些特定的clang的编译警告,因为AFNetworking作为一个库被其他项目引用,所以不能全局忽略clang的一些警告,只能在有需要的时候局部这样做,作者喜欢用?:符号,所以经常见忽略-Wgnu警告的写法,详见这里

B.dispatch_once

为保证线程安全,所有单例都用dispatch_once生成,保证只执行一次,这也是iOS开发常用的技巧。例如:

static dispatch_queue_t url_request_operation_completion_queue() {
    static dispatch_queue_t af_url_request_operation_completion_queue;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        af_url_request_operation_completion_queue = dispatch_queue_create("com.alamofire.networking.operation.queue",   DISPATCH_QUEUE_CONCURRENT );
    });
    return af_url_request_operation_completion_queue;
}

C.weak & strong self

常看到一个block要使用self,会处理成在外部声明一个weak变量指向self,在block里又声明一个strong变量指向weakSelf:

__weak __typeof(self)weakSelf = self;
self.backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^{
    __strong __typeof(weakSelf)strongSelf = weakSelf;
}];

weakSelf是为了block不持有self,避免循环引用,而再声明一个strongSelf是因为一旦进入block执行,就不允许self在这个执行过程中释放。block执行完后这个strongSelf会自动释放,没有循环引用问题。

1.线程

先来看看NSURLConnection发送请求时的线程情况,NSURLConnection是被设计成异步发送的,调用了start方法后,NSURLConnection会新建一些线程用底层的CFSocket去发送和接收请求,在发送和接收的一些事件发生后通知原来线程的Runloop去回调事件。

NSURLConnection的同步方法sendSynchronousRequest方法也是基于异步的,同样要在其他线程去处理请求的发送和接收,只是同步方法会手动block住线程,发送状态的通知也不是通过RunLoop进行。

使用NSURLConnection有几种选择:

A.在主线程调异步接口

若直接在主线程调用异步接口,会有个Runloop相关的问题:

当在主线程调用[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]时,请求发出,侦听任务会加入到主线程的Runloop下,RunloopMode会默认为NSDefaultRunLoopMode。这表明只有当前线程的Runloop处于NSDefaultRunLoopMode时,这个任务才会被执行。但当用户滚动tableview或scrollview时,主线程的Runloop是处于NSEventTrackingRunLoopMode模式下的,不会执行NSDefaultRunLoopMode的任务,所以会出现一个问题,请求发出后,如果用户一直在操作UI上下滑动屏幕,那在滑动结束前是不会执行回调函


转载于:https://my.oschina.net/ospost90s/blog/636284

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值