面试题:AFNetworking 中如何运用 Runloop?

2021-08-31  本文已影响0人  常在士心

AFURLConnectionOperation 这个类是基于 NSURLConnection 构建的,其希望能在后台线程接收 Delegate 回调。为此 AFNetworking 单独创建了一个线程,并在这个线程中启动了一个 RunLoop:

}

AFNetworking 2.0的常驻线程为什么一开始要自动释放池

Using Autorelease Pool Blocks

Each thread in a Cocoa application maintains its own stack of autorelease pool blocks. If you are writing a Foundation-only program or if you detach a thread, you need to create your own autorelease pool block.

当新建线程的时候,需要使用自动释放池。并且涉及到Cocoa编程在合适的地方也要设置自动释放池。

- 为了在释放池块后,立即释放对象

- 开启新的线程时,需要维护自动释放池栈

@autoreleasepool {

    [[NSThread currentThread] setName:@"AFNetworking"];

    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];

    [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];

    [runLoop run];

}

所以上面的代码逻辑是给子线程创建runloop和维持线程等待消息。自动释放池存在的逻辑不是为了释放对象,而是新建线程需要维护自动释放池栈。参考整个app的main函数app启动

}

RunLoop 启动前内部必须要有至少一个 Timer/Observer/Source,所以 AFNetworking 在 [runLoop run] 之前先创建了一个新的 NSMachPort 添加进去了。通常情况下,调用者需要持有这个 NSMachPort (mach_port) 并在外部线程通过这个 port 发送消息到 loop 内;但此处添加 port 只是为了让 RunLoop 不至于退出,并没有用于实际的发送消息。

}

当需要这个后台线程执行任务时,AFNetworking 通过调用 [NSObject performSelector:onThread:..] 将这个任务扔到了后台线程的 RunLoop 中。

作者:投资小白
链接:https://www.jianshu.com/p/d8a63c04914e

上一篇下一篇

猜你喜欢

热点阅读