面试题面试题

AFNetWorking为何在发起请求时要通过runloop。(

2021-04-16  本文已影响0人  L4x

最近几天经历了多场面试,由于简历上写了runloop,跟AFNetworing的字眼。面试官好像特别喜欢问这个问题。一连几场都遇到。
可惜平时开发过程中,知识的累计跟沉淀不足。都不能回答的很好..


趁着现在有时间。查阅一下资料 在这里进行一个总结。。

Question:AFNetworking 2.x怎么开启常驻子线程?为何需要常驻子线程?对应以下代码:

+ (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;
}

首先,我们要了解为何要开启常驻子线程?

NSURLConnection的接口是异步的,然后会在发起的线程回调。而一个子线程,在同步代码执行完成之后,一般情况下,线程就退出了。那么想要接收到NSURLConnection的回调,就必须让子线程至少存活到回调的时机。而AF让线程常驻的原因是,当发起多个http请求的时候,会统一在这个子线程进行回调的处理,所以干脆就让其一直存活下来。

上面说的一般情况,子线程执行完任务就会退出,那么什么情况下,子线程能够继续存活呢?这就涉及到第二个问题了,AF是如何开启常驻线程的,这里实际上考察的是runloop的基础知识。

这里简单来说,当runloop发现还有source/timer/observer的时候,runloop就不会退出。所以AF这里就通过给当前runloop添加一个NSMachPort,这个port实际上相对于添加了一个source事件源,这样子线程的runloop就会一直处于循环状态,等待别的线程向这个port发送消息,而实际上AF这里是没有消息发送到这个port的。

更多关于runloop的知识点总结可以查看这个。深入理解RunLoop

上一篇下一篇

猜你喜欢

热点阅读