Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runloop #122

Open
jhonsmit39 opened this issue Mar 13, 2019 · 1 comment
Open

runloop #122

jhonsmit39 opened this issue Mar 13, 2019 · 1 comment

Comments

@jhonsmit39
Copy link

NSURLConnection afn2.0中开启了子线程的runloop, NSURLSession afn3.0中怎么理解

@ShannonChenCHN
Copy link
Owner

ShannonChenCHN commented Mar 20, 2019

简单说下我的理解吧,仅供参考。

首先,如果我们要用 NSURLConnection 来实现异步请求,该怎么做到?有两种方式:

  • 一种是使用 sendAsynchronousRequest:queue:completionHandler: 方法来实现异步发起请求,但是这种方式只能在主线程中调用,否则会收不到回调
  • 另一种是使用 initWithRequest:delegate:startImmediately: 方法在子线程发起同步请求,但是我们创建的子线程默认情况下是不会开启 runloop 的,请求发起后代码继续往下执行,执行完了请求还没回来线程就被回收了,所以就需要手动开启一个 runloop

另外附一段 YY 大神对 NSURLConnection 的解析:通常使用 NSURLConnection 时,你会传入一个 Delegate,当调用了 [connection start] 后,这个 Delegate 就会不停收到事件回调。实际上,start 这个函数的内部会会获取 CurrentRunLoop,然后在其中的 DefaultMode 添加了4个 Source0 (即需要手动触发的Source)。CFMultiplexerSource 是负责各种 Delegate 回调的,CFHTTPCookieStorage 是处理各种 Cookie 的。

AFNetworking 2.0 和 SDWebImage 3.x 中就是用的上面的第二种方式,在支持异步的 NSOperation 子类中包装一个 NSURLConnection+runloop,然后由 NSOperationQueue 来管理这些 NSOperation 对象。

AFNetworking 3.0 中使用的是 NSURLSession,NSURLSession 是 iOS7 中新增的接口,表面上是和 NSURLConnection 并列的,但底层仍然用到了 NSURLConnection 的部分功能 (比如 com.apple.NSURLConnectionLoader 线程),实际上 NSURLSession 就是扮演着原来 AFNetworking 2.x 的角色,帮我们在异步请求时管理子线程和 runloop。

其实,NSURLConnection 和 NSURLSession 的关键就在于 runloop。

你可以自己写一个简单的 demo,分别在 NSURLConnection 和 NSURLSession 的代理方法回调中创建断点,在 LLDB 中执行 po [NSRunloop currentLoop]po [NSRunloop mainLoop] 看下内容,可以窥见一些端倪。

参考

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants