当开始网络传输时,我们可以看到 NSURLConnection 创建了两个新线程:1、1、com.apple.NSURLConnectionLoader
2、com.apple.CFSocket.private。
其中 CFSocket 线程是处理底层 socket 连接的。NSURLConnectionLoader 这个线程内部会使用 RunLoop 来接收底层 socket 的事件,并通过之前添加的 Source0 通知到上层的 Delegate。
NSURLConnectionLoader 中的 RunLoop 通过一些基于 mach port 的 Source 接收来自底层 CFSocket 的通知。当收到通知后,其会在合适的时机向 CFMultiplexerSource 等 Source0 发送通知,同时唤醒 Delegate 线程的 RunLoop 来让其处理这些通知。CFMultiplexerSource 会在 Delegate 线程的 RunLoop 对 Delegate 执行实际的回调。
查看CFSocket的源码,发现其确实会在首次创建CFSocket的时候创建一个叫CFSocket.private的线程并且通过 __CFSocketManager hold这个线程。
AFURLConnectionOperation 这个类是基于 NSURLConnection 构建的,其希望能在后台线程接收 Delegate 回调。为此 AFNetworking 单独创建了一个线程,并在这个线程中启动了一个 RunLoop:

当需要这个后台线程执行任务时,AFNetworking 通过调用 [NSObject performSelector:onThread:..] 将这个任务扔到了后台线程的 RunLoop 中。
最终完成网络数据通信的是 CFSocket 做底层
CFNetwork 是对 CFSocket 的封装,而 NSURLConnection 又是对 CFNetwork 的封装
NSURLSession 其实内部 还是使用了 NSURLConnection,因为进行数据通信时,还是会创建 com.apple.NSURLConnectionLoader这个子线程
系统完成网络请求时创建了两个系统子线程
com.apple.NSURLConnectionLoader 子线程
com.apple.CFSocket.private 子线程
com.apple.NSURLConnectionLoader 子线程 完成的事情
开启runloop 接收 CFSocket子线程 事件 ,应该是基于 端口 的事件
接收到基于 端口 的事件后,转换成 source0类事件
通知delegate
com.apple.CFSocket.private 子线程 完成的事情
主要是完成CFSocket底层网络数据通信
完成后像 NSURLConnectionLoader子线程 发送 端口消息
网友评论