Runloop是怎樣進(jìn)行線程保活
推薦 + 挑錯(cuò) + 收藏(0) + 用戶評(píng)論(0)
AFN 中的實(shí)現(xiàn)
在舊版本的AFN 中使用了 NSURLConnection 來(lái)發(fā)起并處理網(wǎng)絡(luò)連接。
AFN 的做法是把網(wǎng)絡(luò)請(qǐng)求的發(fā)起和解析都放在同一個(gè)子線程中進(jìn)行,子線程默認(rèn)不開(kāi)啟 runloop,它會(huì)向一個(gè) C語(yǔ)言程序那樣在運(yùn)行完所有代碼后退出線程。
而網(wǎng)絡(luò)請(qǐng)求是異步的,這導(dǎo)致獲取到請(qǐng)求數(shù)據(jù)時(shí),線程已經(jīng)退出,代理方法沒(méi)有機(jī)會(huì)執(zhí)行。
因此,AFN 的做法是使用一個(gè) runloop 來(lái)保證線程不死,也就是下面這段被講爛了的代碼:
+ (void)networkRequestThreadEntryPoint:(id)__unused object {
@autoreleasepool {
?。郏跱SThread currentThread] setName:@“AFNetworking”];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
?。踨unLoop run];
}
}
稍微結(jié)合一下上下文,看看這個(gè)方法在哪里被調(diào)用:
+ (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;
}
似乎這種寫(xiě)法提供了一種思路:“如果需要在子線程中異步執(zhí)行操作,可以利用 runloop 進(jìn)行線程保活”。但準(zhǔn)確的來(lái)說(shuō),AFN 的這種寫(xiě)法并不能實(shí)現(xiàn)我們的需求,它只是在 AFN 這個(gè)特殊場(chǎng)景下可以工作。
NSThread 與內(nèi)存泄漏
這種寫(xiě)法的第一個(gè)問(wèn)題就是存在內(nèi)存泄漏。我們構(gòu)造以下用例,把 AFN 的線程創(chuàng)建放在一個(gè)循環(huán)里:
- (void)memoryTest {
for (int i = 0; i 《 100000; ++i) {
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
?。踭hread start];
}
}
- (void)run {
@autoreleasepool {
NSLog(@“current thread = %@”, [NSThread currentThread]);
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
if (!self.emptyPort) {
self.emptyPort = [NSMachPort port];
}
?。踨unLoop addPort:self.emptyPort forMode:NSDefaultRunLoopMode];
?。踨unLoop run];
}
}
奇怪的事情出現(xiàn)了,盡管是在 ARC 環(huán)境下,內(nèi)存依然不停的上漲。如果我們把 run 方法中和 runloop 相關(guān)的代碼刪除則不會(huì)出現(xiàn)上述問(wèn)題,顯然,開(kāi)啟 runloop 導(dǎo)致了內(nèi)存泄漏,也就是 thread 對(duì)象無(wú)法釋放。
非常好我支持^.^
(1) 100%
不好我反對(duì)
(0) 0%
下載地址
Runloop是怎樣進(jìn)行線程?;钕螺d
相關(guān)電子資料下載
- 一文詳解ZGC關(guān)鍵技術(shù) 26
- AMD推出銳龍 Threadripper 7000系列處理器 171
- 如何使用pthread_barrier_xxx系列函數(shù)來(lái)實(shí)現(xiàn)多線程之間的同步? 29
- SpringBoot物理線程、虛擬線程、Webflux性能比較 37
- SV線程的使用和控制 121
- Python 如何獲取旅游景點(diǎn)信息 82
- 新一輪制裁,摩爾線程、壁仞等IC公司上實(shí)體清單,英偉達(dá)AI芯片限制出售! 927
- 英偉達(dá)H800和A800將禁運(yùn)!美國(guó)將摩爾線程、壁仞列入貿(mào)易管制“黑名單” 301
- i9-14900K/i7-14700K處理器首發(fā)評(píng)測(cè) 134
- 酷睿i7-14700K處理器性能測(cè)試分析 115