美文网首页
AFN为什么添加一条常驻线程

AFN为什么添加一条常驻线程

作者: zziazm | 来源:发表于2018-04-02 15:20 被阅读563次

以前版本的AF里有这样的代码:

+ (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。这个线程就是问题里提到的常驻线程。
这个线程的作用是什么呢?

- (void)start {
    [self.lock lock];
    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];
}

- (void)operationDidStart {
    [self.lock lock];
    if (![self isCancelled]) {
        self.connection = [[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO];
        
        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
        for (NSString *runLoopMode in self.runLoopModes) {
            [self.connection scheduleInRunLoop:runLoop forMode:runLoopMode];
            [self.outputStream scheduleInRunLoop:runLoop forMode:runLoopMode];
        }
        
        [self.connection start];
    }
    [self.lock unlock];
    
    dispatch_async(dispatch_get_main_queue(), ^{
        [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingOperationDidStartNotification object:self];
    });
}

从上面的代码里可以就看出,AF里面把每一个网络请求的发起和解析都放在了这个线程里执行。正常来说,一个线程执行完任务后就退出了。开启runloop是为了防止线程退出。一方面避免每次请求都要创建新的线程;另一方面,因为connection的请求是异步的,如果不开启runloop,线程执行完代码后不会等待网络请求完的回调就退出了,这会导致网络回调的代理方法不执行。

总结:AFN 的做法是把网络请求的发起和解析都放在同一个子线程中进行,但由于子线程默认不开启 runloop,它在运行完所有代码后退出线程。而网络请求是异步的,这会导致获取到请求数据时,线程已经退出,代理方法没有机会执行。因此,AFN 的做法是使用一个 runloop 来保证线程不死,能保证代理方法的执行。同时,避免每次请求都创建新的线程。

相关文章

  • AFN为什么添加一条常驻线程

    title: AFN为什么添加一条常驻线程date: 2017-05-04 15:01:43tags: AFN 的...

  • iOS面试题(九)

    1、AFN2.x为什么添加一条常驻线程? AFN2.0里面把每一个网络请求的发起和解析都放在了一个线程里执行。正常...

  • AFN常驻线程的理解(从2.x到3.x)

    最常见的问题:AFN为什么添加一条常驻线程 问这个问题的人大部分是停留在2.x版本的理解,从3.x开始AFN已经不...

  • AFN为什么添加一条常驻线程

    以前版本的AF里有这样的代码: 上面的代码是创建了一个线程并且开启了它的runloop。这个线程就是问题里提到的常...

  • AFN为什么添加一条常驻线程

    AFN 的做法是把网络请求的发起和解析都放在同一个子线程中进行,但由于子线程默认不开启 runloop,它会向一个...

  • 实现后台常驻线程

    添加一条用于常驻内存的强引用的子线程,在该线程的RunLoop下添加一个Sources,开启RunLoop。

  • 常驻线程

    模仿曾经的AFN常驻线程写法,现在的YY的写法也是如此 使用performSelector: onThread:简...

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

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

  • 浏览器和主引擎

    浏览器是多线程,js是异步单线程 ps:常驻线程一直存在,一直在待命。非常驻线程有需求的时候线程才会工作。 常驻线...

  • AFN 同步请求

    需要把AFN的回调 放置在子线程 AFN的回调 默认在主线程,如果不把回调设置子线程, 那么 dispatch_s...

网友评论

      本文标题:AFN为什么添加一条常驻线程

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