美文网首页
AFNetworking 2.6.3 - Why does it

AFNetworking 2.6.3 - Why does it

作者: 公爵海恩庭斯 | 来源:发表于2018-05-11 14:53 被阅读19次

    为什么 AFNetworking 2.6.3 要包装一个独立的线程?

    image.png

    Some important factors:

    • NSOperationQueue 使用 GCD 创建线程

    Operation queues use the Dispatch framework to initiate the execution of their operations. As a result, operations are always executed on a separate thread, regardless of whether they are designated as synchronous or asynchronous.

    • NSURLConnection delegate 默认会使用调用时的线程进行回调

    As such we can reason that the thread exists because at the time it was written we can see that making a thread and scheduling your connections on it was the only way to receive callbacks from NSURLConnection in the background while running in an asynchronous NSOperation subclass.

    当然,spawn 一个 thread 并不是解决 NSOperation + NSURLConnection 问题的唯一手段,NSURLConnection 本身通过引入 delegateQueue 来解决这个问题:

    NSURLConnection* connection = [[NSURLConnection alloc] initWithRequest:request
                                                              delegate:self
                                                      startImmediately:NO];
    [connection setDelegateQueue:[[NSOperationQueue alloc] init]];
    [connection start];
    

    为什么 SDWebImage 4.4.3 没有使用类似的设计?

    这是因为 SDWebImage 4.4.3 与 AFNetworking 3.1.0 相同,是在 NSURLSession 的基础上进行的封装。NSURLSession 也引入了 NSURLConnection delegateQueue 的概念,并将其作为了线程回调问题的唯一手段。如果设置的 delegateQueue 为 nil,NSURLSession 会直接回调主线程。SDWebImage 作为一个视图层的框架,回调到主线程刚好满足它只有在主线程才能操作 UI 对象的需求。

    - (void)createNewSessionWithConfiguration:(NSURLSessionConfiguration *)sessionConfiguration {
        [self cancelAllDownloads];
    
        if (self.session) {
            [self.session invalidateAndCancel];
        }
    
        sessionConfiguration.timeoutIntervalForRequest = self.downloadTimeout;
    
        /**
         *  Create the session for this task
         *  We send nil as delegate queue so that the session creates a serial operation queue for performing all delegate
         *  method calls and completion handler calls.
         */
        self.session = [NSURLSession sessionWithConfiguration:sessionConfiguration
                                                     delegate:self
                                                delegateQueue:nil];
    }
    

    那么 AFNetworking 3.1.0 呢?

    AFNetworking 3.1.0 也是在 NSURLSession 的基础上进行工作的。线程回调问题,AFNetworking 3.1.0 与 SDWebImage 4.4.3 相同,都是通过 delegateQueue 来解决的。

    - (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {
        self = [super init];
        if (!self) {
            return nil;
        }
    
        if (!configuration) {
            configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        }
    
        self.sessionConfiguration = configuration;
    
        self.operationQueue = [[NSOperationQueue alloc] init];
        self.operationQueue.maxConcurrentOperationCount = 1;
    
        self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];
    
        // ...
    
        return self;
    }
    
    

    另外,AFNetworking 3.1.0 并没有使用 NSOperationQueue。因为 NSURLSession 本身有它自己的并发控制,而 NSURLConnection 没有。这是另一个话题。

    @interface NSURLSessionConfiguration : NSObject <NSCopying>
    
    // ...
    
    @property NSInteger HTTPMaximumConnectionsPerHost;
    
    // ...
    
    @end
    
    • NSURLSession.h

    这也是一个讨巧的设计,因为 AFHTTPSessionManager 引入了 baseURL,这意味着 NSURLSession 的 HTTPMaximumConnectionsPerHost 与 AFHTTPSessionManager 本身的最大并发数是等价的。

    相关文章

      网友评论

          本文标题:AFNetworking 2.6.3 - Why does it

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