Android 程式設計師學習 iOS —— 線上程間跳舞

Gemini發表於2016-02-28

跨執行緒更新UI

在客戶端開發的過程中,我們經常碰到的問題有可能就是 IO 請求完成後,在主執行緒中更新 UI 這件事了,看見這個問題,我們一般會直接想到 Handler這個大殺器,

Android 中我們知道有LooperHandler這兩種神器幫我們完成不同執行緒間的排程,那麼在iOS中如何實現不同執行緒間的切換呢?答案就是NSOperationQueueNSOperation。變數名字直接翻譯就是操作佇列操作,那麼,更新 UI 就是一個操作。 因為Objective-C帶了blockselector兩個神器,使用閉包比在java中使用Runnable方便許多,所以我們的NSOperation更像是一個Runnable,而NSOperationQueue就像LooperHandler的結合體,我們來看看如何建立一個 UI 執行緒上的訊息佇列吧。

主執行緒上的訊息佇列

建立一個主執行緒上的訊息佇列,只用一條函式

NSOperationQueue *queue = [NSOperationQueue mainQueue];

這和java建立一個mainLooper上的Handler如出一轍:

Handler uiHandler = new Handler(Looper.mainLooper());

從客戶端的層面上來說,這兩句話是等價的。
然後我們呼叫

[queue addOperation:...]

傳入一個Operation,OS就會在適當的時候,在主執行緒上回撥我們的Operation,這和Handler呼叫handlerMessage是如何的一致啊~

子執行緒上的訊息佇列

那麼,如何在子執行緒上呼叫一個NSOperation呢?
我們知道在Android中,需要將Handler的初始化執行在子執行緒上,因為這樣才能用Looper.myLooper()獲取執行緒本地變數例項。
但是在iOS中,我們不需要顯示的在一條新的執行緒中完成我們的工作,我們只需要使用傳統的分配物件的方法:

NSOperationQueue *queue = [NSOperationQueue mainQueue];

OS這時候已經自動幫我們分配了一個訊息佇列(但是不同的是,它並不像Android OS上一樣,是繫結到執行緒上的,也就是說,這個訊息佇列,可以併發),我們只需要像上面一樣,使用[queue addOperation:...]即可。

實驗

我們來看看例項好了,先看mainQueue上的實驗:

self.queue = [NSOperationQueue mainQueue];
[self.queue addOperation:[NSBlockOperation blockOperationWithBlock:^() {
        NSLog(@"%@", [NSThread currentThread]);
}]];

Output:

2016-02-28 15:10:38.813 OperationQueue[1277:52212] <NSThread: 0x7fd44a505670>{number = 1, name = main}

看到我們這個block的執行的確是在主執行緒上的。
然後看新的訊息佇列:

self.queue = [[NSOperationQueue alloc] init];
[self.queue addOperation:[NSBlockOperation blockOperationWithBlock:^() {
        NSLog(@"%@", [NSThread currentThread]);
}]];

Output:

2016-02-28 15:23:03.954 OperationQueue[1375:64592] <NSThread: 0x7fe10b5136d0>{number = 2, name = (null)}

這就不是在主執行緒了,那麼在iOS上使用”Handler“或者說訊息佇列的方法就是這麼簡單啦~

One more thing —— 佇列和執行緒的繫結

上一個章節我們說,在iOS中,執行緒和佇列並不是一一對應繫結的,我們可以簡單的理解成在iOS中,除了main queue以外,自己生成的佇列是可以併發的,簡單的操作就是在生成佇列的時候,指定maxConcurrentOperationCount屬性即可,我們的操作佇列就具有了併發的功能(不過這樣嚴格意義上就不是FIFO,也就是說,它其實不應該被稱作”佇列”了)

參考資料

Working with NSOperationQueue

Apple官方教程 —— Concurrency Programming Guide

相關文章