最近幾天經(jīng)歷了多場(chǎng)面試,由于簡(jiǎn)歷上寫(xiě)了runloop衷蜓,跟AFNetworing的字眼累提。面試官好像特別喜歡問(wèn)這個(gè)問(wèn)題。一連幾場(chǎng)都遇到磁浇。
可惜平時(shí)開(kāi)發(fā)過(guò)程中,知識(shí)的累計(jì)跟沉淀不足斋陪。都不能回答的很好..
趁著現(xiàn)在有時(shí)間。查閱一下資料 在這里進(jìn)行一個(gè)總結(jié)置吓。无虚。
Question:AFNetworking 2.x怎么開(kāi)啟常駐子線程?為何需要常駐子線程衍锚?對(duì)應(yīng)以下代碼:
+ (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;
}
首先友题,我們要了解為何要開(kāi)啟常駐子線程?
NSURLConnection的接口是異步的戴质,然后會(huì)在發(fā)起的線程回調(diào)度宦。而一個(gè)子線程,在同步代碼執(zhí)行完成之后告匠,一般情況下戈抄,線程就退出了。那么想要接收到NSURLConnection的回調(diào)后专,就必須讓子線程至少存活到回調(diào)的時(shí)機(jī)划鸽。而AF讓線程常駐的原因是,當(dāng)發(fā)起多個(gè)http請(qǐng)求的時(shí)候戚哎,會(huì)統(tǒng)一在這個(gè)子線程進(jìn)行回調(diào)的處理漾稀,所以干脆就讓其一直存活下來(lái)。
上面說(shuō)的一般情況建瘫,子線程執(zhí)行完任務(wù)就會(huì)退出崭捍,那么什么情況下,子線程能夠繼續(xù)存活呢啰脚?這就涉及到第二個(gè)問(wèn)題了殷蛇,AF是如何開(kāi)啟常駐線程的,這里實(shí)際上考察的是runloop的基礎(chǔ)知識(shí)橄浓。
這里簡(jiǎn)單來(lái)說(shuō)粒梦,當(dāng)runloop發(fā)現(xiàn)還有source/timer/observer的時(shí)候,runloop就不會(huì)退出荸实。所以AF這里就通過(guò)給當(dāng)前runloop添加一個(gè)NSMachPort匀们,這個(gè)port實(shí)際上相對(duì)于添加了一個(gè)source事件源,這樣子線程的runloop就會(huì)一直處于循環(huán)狀態(tài)准给,等待別的線程向這個(gè)port發(fā)送消息泄朴,而實(shí)際上AF這里是沒(méi)有消息發(fā)送到這個(gè)port的重抖。
更多關(guān)于runloop的知識(shí)點(diǎn)總結(jié)可以查看這個(gè)。深入理解RunLoop