原因有2個(gè):
1仍秤、在子線程中是不能進(jìn)行UI 更新的,而可以更新的結(jié)果只是一個(gè)幻像:因?yàn)樽泳€程代碼執(zhí)行完畢了可很,又自動(dòng)進(jìn)入到了主線程诗力,執(zhí)行了子線程中的UI更新的函數(shù)棧,這中間的時(shí)間非常的短我抠,就讓大家誤以為分線程可以更新UI苇本。如果子線程一直在運(yùn)行,則子線程中的UI更新的函數(shù)棧 主線程無(wú)法獲知屿良,即無(wú)法更新2圈澈、只有極少數(shù)的UI能,因?yàn)殚_(kāi)辟線程時(shí)會(huì)獲取當(dāng)前環(huán)境尘惧,如點(diǎn)擊某個(gè)按鈕康栈,這個(gè)按鈕響應(yīng)的方法是開(kāi)辟一個(gè)子線程,在子線程中對(duì)該按鈕進(jìn)行UI 更新是能及時(shí)的喷橙,如換標(biāo)題啥么,換背景圖,但這沒(méi)有任何意義贰逾。
1悬荣、程序一開(kāi)始運(yùn)行就進(jìn)入了主線程
2、處理某些數(shù)據(jù)太過(guò)費(fèi)時(shí)疙剑,影響用戶交互氯迂,可以開(kāi)辟子線程處理,然后通知主線程進(jìn)行界面更新測(cè)試代碼:開(kāi)辟一個(gè)多線程言缤,直接在子線程里進(jìn)行ui 更新:
- (void)testUIRefresh:(UIButton *)button{
? ? ?[NSThread detachNewThreadSelector:@selector(beginTest) toTarget:self withObject:nil];
}
- (void)beginTest{
? ? NSLog(@” 當(dāng)前線程%@”,[NSThreadcurrentThread]);
? ? NSLog(@” 主線程%@”,[NSThreadmainThread]);
? ?//該button 為響應(yīng) testUIRefresh的button
? ?[self.button setTitle:@"AAA" forState:0];
}
2012-11-15 12:14:02.147 TestProj[2455:1b07]當(dāng)前線程{name = (null), num = 3}
2012-11-15 12:14:02.147 TestProj[2455:1b07]主線程{name = (null), num = 1}結(jié)果:當(dāng)前的確是在子線程中嚼蚀,但是UI馬上更新了?管挟?
結(jié)果分析:大家都說(shuō)UI更新在主線程中做轿曙,上面的結(jié)果怎么解釋
假設(shè):如果在子線程里做了UI更新,待子線程運(yùn)行完畢,程序自動(dòng)進(jìn)入 主線程進(jìn)行指定的ui更新导帝!
問(wèn)題:如果子線程沒(méi)結(jié)束呢守谓?
在分線程中加入:
-(void)beginTest{
NSLog(@” 當(dāng)前線程%@”,[NSThreadcurrentThread]);
NSLog(@” 主線程%@”,[NSThreadmainThread]);
//該button 為響應(yīng) testUIRefresh的button
[self.button setTitle:@"AAA" forState:0];
[NSThread sleepForTimeInterval:4.0];
}
結(jié)果:
self.button的title還是馬上更新了
結(jié)果分析:難道上面的假設(shè)不成立?
問(wèn)題:這次在分線程中add 一個(gè)button
-(void)beginTest{
NSLog(@” 當(dāng)前線程%@”,[NSThreadcurrentThread]);
NSLog(@” 主線程%@”,[NSThreadmainThread]);
//該button 為響應(yīng) testUIRefresh的button
[self.button setTitle:@"AAA" forState:0];
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[backButton setTitle:@"測(cè)試runloop" forState:0];
[backButton setTitleColor:[UIColor redColor] forState:0];
backButton.frame = CGRectMake(100, 200, 100, 50);
[backButton addTarget:self action:@selector(testRunLoop)forControlEvents:UIControlEventTouchUpInside];
[self.window addSubview:backButton];[NSThread sleepForTimeInterval:4.0];
}
結(jié)果:[self.button setTitle:@"AAA" forState:0];之前button馬上響應(yīng)了您单,但是添加的這個(gè)Button卻一直等到線程結(jié)束才繪制出來(lái)分析:在子線程中:如果要對(duì)其他UI 進(jìn)行更新斋荞,則必須等到該子線程運(yùn)行結(jié)束,而對(duì)響應(yīng)用戶點(diǎn)擊的Button的UI更新則是及時(shí)的睹限!不管他是在主線程還是在子線程中做的更新譬猫,意義都不大了,因?yàn)樽泳€程中對(duì)所有其他ui更新都要等到該子線程生命周期結(jié)束才進(jìn)行羡疗。
結(jié)論:1、在子線程中是不能進(jìn)行UI 更新的别洪,而可以更新的結(jié)果只是一個(gè)幻像:因?yàn)樽泳€程代碼執(zhí)行完畢了叨恨,又自動(dòng)進(jìn)入到了主線程,執(zhí)行了子線程中的UI更新的函數(shù)棧挖垛,這中間的時(shí)間非常的短痒钝,就讓大家誤以為分線程可以更新UI。如果子線程一直在運(yùn)行痢毒,則子線程中的UI更新的函數(shù)棧 主線程無(wú)法獲知送矩,即無(wú)法更新。
2哪替、只有極少數(shù)的UI能栋荸,因?yàn)殚_(kāi)辟線程時(shí)會(huì)獲取當(dāng)前環(huán)境,如點(diǎn)擊某個(gè)按鈕凭舶,這個(gè)按鈕響應(yīng)的方法是開(kāi)辟一個(gè)子線程晌块,在子線程中對(duì)該按鈕進(jìn)行UI 更新是能及時(shí)的,如換標(biāo)題帅霜,換背景圖匆背,但這沒(méi)有任何意義。