AFURLConnectionOperation
这个类是基于 NSURLConnection
构建的,其希望能在后台线程接收 Delegate
回调。为此 AFNetworking
单独创建了一个线程,并在这个线程中启动了一个 RunLoop
:
+ (void)networkRequestThreadEntryPoint:(id)__unused object {
@autoreleasepool {
[[NSThread currentThread] setName:@"AFNetworking"];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
[runLoop run];
}
}
+ (NSThread *)networkRequestThread {
static NSThread *_networkRequestThread = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_networkRequestThread = [[NSThread alloc] initWithTarget:self selector:@selector(networkRequestThreadEntryPoint:) object:nil];
[_networkRequestThread start];
});
return _networkRequestThread;
}
RunLoop
启动前内部必须要有至少一个 Timer
/Observer
/Source
,所以 AFNetworking
在 [runLoop run]
之前先创建了一个新的 NSMachPort
添加进去了。通常情况下,调用者需要持有这个 NSMachPort (mach_port)
并在外部线程通过这个 port
发送消息到 loop
内;但此处添加 port
只是为了让 RunLoop
不至于退出,并没有用于实际的发送消息。
- (void)start {
[self.lock lock];
if ([self isCancelled]) {
[self performSelector:@selector(cancelConnection) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]];
} else if ([self isReady]) {
self.state = AFOperationExecutingState;
[self performSelector:@selector(operationDidStart) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]];
}
[self.lock unlock];
}
当需要这个后台线程执行任务时,AFNetworking
通过调用 [NSObject performSelector:onThread:..]
将这个任务扔到了后台线程的 RunLoop
中。