AFNetworking 2.6.3 - Why does it spawn a network request thread?

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

AFNetworking 2.6.3 - Why does it spawn a network request thread?_第1张图片
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.

  • https://developer.apple.com/documentation/foundation/nsoperationqueue
  • 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.

  • AFNetworking - Why does it spawn a network request thread?

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

NSURLConnection* connection = [[NSURLConnection alloc] initWithRequest:request
                                                          delegate:self
                                                  startImmediately:NO];
[connection setDelegateQueue:[[NSOperationQueue alloc] init]];
[connection start];
  • NSURLConnection started in another thread. Delegate methods not called

为什么 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];
}
  • SDWebImageDownloader.m

那么 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;
}

  • AFURLSessionManager.m

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

@interface NSURLSessionConfiguration : NSObject 

// ...

@property NSInteger HTTPMaximumConnectionsPerHost;

// ...

@end
  • NSURLSession.h

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

你可能感兴趣的:(AFNetworking 2.6.3 - Why does it spawn a network request thread?)