美文网首页
AFNetworking

AFNetworking

作者: hehc08 | 来源:发表于2019-01-26 17:28 被阅读0次

    AF2.x为什么需要常驻线程?

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

    开辟一条子线程,设置runloop使线程常驻。所有的请求在这个线程上发起、同时也在这个线程上回调。

    由这个NSOperationQueue来控制并发

    AFNetworking3.0后为什么不再需要常驻线程?

    NSURLSession发起的请求,不再需要在当前线程进行代理方法的回调!可以指定回调的delegateQueue,这样我们就不用为了等待代理回调方法而苦苦保活线程了。

    同时还要注意一下,指定的用于接收回调的Queue的maxConcurrentOperationCount设为了1,这里目的是想要让并发的请求串行的进行回调。

    为什么要串行回调?

    - (AFURLSessionManagerTaskDelegate *)delegateForTask:(NSURLSessionTask *)task {
        NSParameterAssert(task);
        AFURLSessionManagerTaskDelegate *delegate = nil;
        [self.lock lock];
        //给所要访问的资源加锁,防止造成数据混乱
        delegate = self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)];
        [self.lock unlock];
        return delegate;
    }
    

    这边对 self.mutableTaskDelegatesKeyedByTaskIdentifier 的访问进行了加锁,目的是保证多线程环境下的数据安全。既然加了锁,就算maxConcurrentOperationCount不设为1,当某个请求正在回调时,下一个请求还是得等待一直到上个请求获取完所要的资源后解锁,所以这边并发回调也是没有意义的。相反多task回调导致的多线程并发,还会导致性能的浪费。

    补充

    • AF3.x会给每个 NSURLSessionTask 绑定一个 AFURLSessionManagerTaskDelegate ,这个TaskDelegate相当于把NSURLSessionDelegate进行了一层过滤,最终只保留类似didCompleteWithError这样对上层调用者输出的回调。

    • AF3.0的operationQueue是用来接收NSURLSessionDelegate回调的,鉴于一些多线程数据访问的安全性考虑,设置了maxConcurrentOperationCount = 1来达到串行回调的效果。
      而AF2.0的operationQueue是用来添加operation并进行并发请求的,所以不要设置为1

    NSURLConnection代理方法线程问题

    NSURLConnection代理方法默认在主线程执行
    让代理方法在子线程执行的方法 1.给代理方法开子线程(若方法多 开子线程越多 不建议使用)2. 统一开线程

    相关文章

      网友评论

          本文标题:AFNetworking

          本文链接:https://www.haomeiwen.com/subject/hjwijqtx.html