iOS 開發(fā)中為什么更新UI都要放在主線程中属韧?--轉(zhuǎn)
(2014-10-17 15:06:56)
標簽:
原因有2個:
1、在子線程中是不能進行UI 更新的盏求,而可以更新的結(jié)果只是一個幻像:因為子線程代碼執(zhí)行完畢了抖锥,又自動進入到了主線程亿眠,執(zhí)行了子線程中的UI更新的函數(shù)棧,這中間的時間非常的短磅废,就讓大家誤以為分線程可以更新UI纳像。如果子線程一直在運行,則子線程中的UI更新的函數(shù)棧 主線程無法獲知拯勉,即無法更新
2竟趾、只有極少數(shù)的UI能,因為開辟線程時會獲取當前環(huán)境宫峦,如點擊某個按鈕岔帽,這個按鈕響應(yīng)的方法是開辟一個子線程,在子線程中對該按鈕進行UI 更新是能及時的导绷,如換標題山卦,換背景圖,但這沒有任何意義
1诵次、程序一開始運行就進入了主線程
2、處理某些數(shù)據(jù)太過費時枚碗,影響用戶交互逾一,可以開辟子線程處理,然后通知主線程進行界面更新
測試代碼:
開辟一個多線程肮雨,直接在子線程里進行ui 更新:
-(void)testUIRefresh:(UIButton *)button{
[NSThread detachNewThreadSelector:@selector(beginTest) toTarget:self withObject:nil];
}
-(void)beginTest{
NSLog(@” 當前線程%@”,[NSThreadcurrentThread]);
NSLog(@” 主線程%@”,[NSThreadmainThread]);
//該button 為響應(yīng) testUIRefresh的button
[self.button setTitle:@"AAA" forState:0];
}
2012-11-15 12:14:02.147 TestProj[2455:1b07]當前線程{name = (null), num = 3}
2012-11-15 12:14:02.147 TestProj[2455:1b07]主線程{name = (null), num = 1}
結(jié)果:當前的確是在子線程中遵堵,但是UI馬上更新了?怨规?
結(jié)果分析:大家都說UI更新在主線程中做陌宿,上面的結(jié)果怎么解釋
假設(shè):如果在子線程里做了UI更新,待子線程運行完畢波丰,程序自動進入 主線程進行指定的ui更新壳坪!
問題:如果子線程沒結(jié)束呢?
在分線程中加入:
-(void)beginTest{
NSLog(@” 當前線程%@”,[NSThreadcurrentThread]);
NSLog(@” 主線程%@”,[NSThreadmainThread]);
//該button 為響應(yīng) testUIRefresh的button
[self.button setTitle:@"AAA" forState:0];
[NSThread sleepForTimeInterval:4.0];
}
結(jié)果:
self.button的title還是馬上更新了
結(jié)果分析:難道上面的假設(shè)不成立掰烟?
問題:這次在分線程中add 一個button
-(void)beginTest{
NSLog(@” 當前線程%@”,[NSThreadcurrentThread]);
NSLog(@” 主線程%@”,[NSThreadmainThread]);
//該button 為響應(yīng) testUIRefresh的button
[self.button setTitle:@"AAA" forState:0];
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[backButton setTitle:@"測試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];馬上響應(yīng)了爽蝴,但是添加的這個Button卻一直等到線程結(jié)束才繪制出來
分析:在子線程中:如果要對其他UI 進行更新,則必須等到該子線程運行結(jié)束纫骑,而對響應(yīng)用戶點擊的Button的UI更新則是及時的蝎亚!不管他是在主線程還是在子線程中做的更新,意義都不大了先馆,因為子線程中對所有其他ui更新都要等到該子線程生命周期結(jié)束才進行发框。
結(jié)論:
1、在子線程中是不能進行UI 更新的煤墙,而可以更新的結(jié)果只是一個幻像:因為子線程代碼執(zhí)行完畢了梅惯,又自動進入到了主線程宪拥,執(zhí)行了子線程中的UI更新的函數(shù)棧,這中間的時間非常的短个唧,就讓大家誤以為分線程可以更新UI江解。如果子線程一直在運行,則子線程中的UI更新的函數(shù)棧 主線程無法獲知徙歼,即無法更新
2犁河、只有極少數(shù)的UI能,因為開辟線程時會獲取當前環(huán)境魄梯,如點擊某個按鈕桨螺,這個按鈕響應(yīng)的方法是開辟一個子線程,在子線程中對該按鈕進行UI 更新是能及時的酿秸,如換標題灭翔,換背景圖,但這沒有任何意義