1. 程式人生 > >iOS 主執行緒更新UI

iOS 主執行緒更新UI

方法1performSelectorOnMainThread

[self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:NO];

方法2dispatch_async(dispatch_get_main_queue(), ^{ ... })

  1. dispatch_async(dispatch_get_global_queue(0, 0), ^{  
  2. // 處理耗時操作的程式碼塊...
  3.     //通知主執行緒重新整理  
  4.     dispatch_async(dispatch_get_main_queue(), ^{  
  5. //回撥或者說是通知主執行緒重新整理,
  6.     });  
  7. });  

dispatch_async開啟一個非同步操作,第一個引數是指定一個gcd佇列,第二個引數是分配一個處理事物的程式塊到該佇列。

dispatch_get_global_queue(0, 0),指用了全域性佇列。

一般來說系統本身會有3個佇列。global_queuecurrent_queue,以及main_queue.

獲取一個全域性佇列是接受兩個引數,第一個是我分配的事物處理程式塊佇列優先順序。分高低和預設,0為預設2為高,-2為低

  1. #define DISPATCH_QUEUE_PRIORITY_HIGH     2
  2. #define DISPATCH_QUEUE_PRIORITY_DEFAULT  0
  3. #define DISPATCH_QUEUE_PRIORITY_LOW     (-2)

處理完事物後,需要將結果返回給或者是重新整理UI主執行緒,同樣,和上面一樣,抓取主執行緒,程式塊操作。

原因有2個:

1、在子執行緒中是不能進行UI 更新的,而可以更新的結果只是一個幻像:因為子執行緒程式碼執行完畢了,又自動進入到了主執行緒,執行了子執行緒中的UI更新的函式棧,這中間的時間非常的短,就讓大家誤以為分執行緒可以更新UI。如果子執行緒一直在執行,則子執行緒中的UI更新的函式棧 主執行緒無法獲知,即無法更新 2、只有極少數的UI能,因為開闢執行緒時會獲取當前環境,如點選某個按鈕,這個按鈕響應的方法是開闢一個子執行緒,在子執行緒中對該按鈕進行UI 更新是能及時的,如換標題,換背景圖,但這沒有任何意義 

1、程式一開始執行就進入了主執行緒 2、處理某些資料太過費時,影響使用者互動,可以開闢子執行緒處理,然後通知主執行緒進行介面更新 測試程式碼: 開闢一個多執行緒,直接在子執行緒裡進行ui 更新: -(void)testUIRefresh:(UIButton *)button{

       [NSThread detachNewThreadSelector:@selector(beginTest) toTarget:self withObject:nil];

} -(void)beginTest {       NSLog(@” 當前執行緒  %@”,[NSThread currentThread]);

       NSLog(@” 主執行緒    %@”,[NSThread mainThread]);

      //該button 為  響應 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} 結果:當前的確是在子執行緒中,但是UI馬上更新了??

結果分析:大家都說UI更新在主執行緒中做,上面的結果怎麼解釋

假設:如果在子執行緒裡做了UI更新,待子執行緒執行完畢,程式自動進入 主執行緒進行指定的ui更新!

問題:如果子執行緒沒結束呢?

在分執行緒中加入:-(void)beginTest{      NSLog(@” 當前執行緒  %@”,[NSThread currentThread]);

      NSLog(@” 主執行緒    %@”,[NSThread mainThread]);

      //該button 為  響應 testUIRefresh的button

      [self.button setTitle:@"AAA" forState:0];

      [NSThread sleepForTimeInterval:4.0];

} 結果:

self.button的title還是馬上更新了

結果分析:難道上面的假設不成立?

問題:這次在分執行緒中add 一個button

-(void)beginTest{

      NSLog(@” 當前執行緒  %@”,[NSThread currentThread]);

      NSLog(@” 主執行緒    %@”,[NSThread mainThread]);

      //該button 為  響應 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];

} 結果:[self.button setTitle:@"AAA" forState:0];馬上響應了,但是新增的這個Button卻一直等到執行緒結束才繪製出來 分析:在子執行緒中:如果要對其他UI 進行更新,則必須等到該子執行緒執行結束,而對響應使用者點選的Button的UI更新則是及時的!不管他是在主執行緒還是在子執行緒中做的更新,意義都不大了,因為子執行緒中對所有其他ui更新都要等到該子執行緒生命週期結束才進行。   結論: 1、在子執行緒中是不能進行UI 更新的,而可以更新的結果只是一個幻像:因為子執行緒程式碼執行完畢了,又自動進入到了主執行緒,執行了子執行緒中的UI更新的函式棧,這中間的時間非常的短,就讓大家誤以為分執行緒可以更新UI。如果子執行緒一直在執行,則子執行緒中的UI更新的函式棧 主執行緒無法獲知,即無法更新 2、只有極少數的UI能,因為開闢執行緒時會獲取當前環境,如點選某個按鈕,這個按鈕響應的方法是開闢一個子執行緒,在子執行緒中對該按鈕進行UI 更新是能及時的,如換標題,換背景圖,但這沒有任何意義


相關推薦

iOS 執行更新UI

方法1:performSelectorOnMainThread [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:NO]; 方法2:dispa

iOS沉思錄】iOS執行更新UI執行的三種方法

簡單說將程式碼同步到主執行緒執行的三種方法如下: // 1.NSThread [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO];

為什麼Android必須在執行更新UI

為什麼Android必須在主執行緒更新UI? 站在各位大牛的肩膀上,謝謝! 正常情況下,Android需要在UI執行緒更新UI,然鵝,在特殊情況下,子執行緒也能更新UI不在討論之列,可參考Android中子執行緒真的不能更新UI嗎?這篇文章主要講一下個人理解的正常情況下為什麼不能在非

post請求網路資料,返回給執行更新UI例項

postHttp封裝的程式碼 package honghu.com.test.http; import android.os.Bundle; import android.os.Handler; im

“只能在UI執行更新View”這件小事,android ui

轉載請註明出處:http://blog.csdn.net/zhaokaiqiang1992     ”只能在UI主執行緒中更新View“。     這句話很熟悉吧?     來來,哥們,看一下下面的例子 @Override protected void onCreate(

ios執行初步,執行重新整理UI

去研究一下iOS多執行緒的起因是自己程式裡用了一個等待指示器UIActivityIndicatorView,俗稱小菊花。但是在給頂層ViewController用addsubview加入這個控制元件並使轉動時,螢幕並沒有出現菊花。經過好一番除錯都沒找到原因。去網

安卓4.0以後執行訪問網路問題(NetworkOnMainThreadException)解決方法及子執行更新ui

安卓4.0之後谷歌建議不在主執行緒訪問網路,可能是因為訪問網路可能會等待時間長造成假死現象,解決辦法無非是強行訪問和開一個子執行緒訪問 1.強行訪問: 在activity裡面onCreate方法裡面加

ios 中請求執行重新整理UI

IOS中只有主執行緒 才能立即重新整理UI。如果是通過偵聽非同步訊息,觸發回撥函式,或者呼叫非同步方法,請求重新整理UI,都會產生執行緒阻塞和延遲的問題。 可以通過  if ([NSThread isMainThread]) {

執行更新ui相關

1.Android載入view有兩種方式:一是setContentView,二是inflater.inflate() 2.子執行緒其實是可以更新ui的,需要viewRoot,ViewRoot本質是一個Handler,作用是建立View與WindowsManger的通訊。通過Windowmanag

Android ActivityThread 執行UI執行 簡介

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Android複習之旅--子執行更新UI

Android4.0版本後耗時的操作(比如請求網路,下載檔案等)不能在UI主執行緒執行,而且子執行緒也不能直接更新UI介面。而現實的場景確是子執行緒在下載檔案的同時UI介面能顯示相應的進度資訊,既然有了需求,那肯定就會有解決方案。 Android提供了Handler訊息機制和Asyn

WPF 執行更新UI介面

線上程中無法直接操作UI元素,可以通過執行緒的Dispatch.Invoke方法來更新UI介面。 XAML介面 <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

Android中使用非同步執行更新UI檢視的幾種方法

在Android中子執行緒是不能更新ui的。 所以我們要通過其他方式來動態改變ui檢視, 1、runOnUiThreadactivity提供的一個輕量級更新ui的方法,在Fragment需要使用的時候要用getActivity.runOnUiThread開啟執行緒 這種方法最簡單,方便更新一些不需要判斷的

[iOS]執行同步派發一個block任務死鎖問題

- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib.

Android 子執行更新UI【通過RunOnUI】

在Fragment中無法直接使用runonuithread   runOnUiThread這個方法只存在於Activity中,想用它必須獲取Activity的例項。   MainActiivty.this.runOnUiThread(),就沒問

Android 子執行更新UI 異常

眾所周知,Android是不可以在子執行緒中直接更新UI的,需要藉助Handler或者View.post(Runnable runnable)或者runOnUIThread(Runnable runnable)將更新的程式碼切入到主執行緒中去實現UI更新。 我們來試一下,在Activity的 onCreat

Android在子執行更新UI方式總結

1.Handler方式 —————-複寫handler的handleMessage方式——————- //在UI執行緒中建立Handler物件 private Handler mHandler = new Handler(){ @Overrid

python3多執行更新UI資料,pyqt5介面重新整理

本程式碼執行python3,pyqt5環境下。在編寫介面程式的時候經常會執行一些耗時的操作,所以我們要使用多執行緒來做耗時任務,主執行緒用來重繪介面。而子執行緒裡邊的實時處理結果需要反饋到介面。而總所

Python+PyQT5的子執行更新UI介面

子執行緒裡是不能更新UI介面的,在移動端方面。Android的UI訪問是沒有加鎖的,多個執行緒可以同時訪問更新操作同一個UI控制元件。也就是說訪問UI的時候,android系統當中的控制元件都不是執行緒安全的,這將導致在多執行緒模式下,當多個執行緒共同訪問更新操作同一個UI控制元件時容易發生不可

Qt子執行更新UI的方法

     最近剛剛接觸一個qt專案,由於原始程式中的listwidget裡有大量的item,每一個item都有一個按鈕,這樣導致程式執行起來後,生成按鈕的速度很慢,嚴重影響了軟體的使用體驗。於是將生成按鈕的操作放到子執行緒中。一開始我是直接在子執行緒中生成按鈕來更新UI的,