2010-05-13 80 views
1

我想阻塞主線程,直到在後臺完成其他事情。NSOperationqueue我想阻止主線程

我用:

result=[self performSelectorInBackground:@selector(calculate:) withObject:expression]; 

只是吼叫此行我使用的結果是:

[self use:result]; 

我不想使用結果,直到它可用。 實現這一目標,我實現

-calculate: 
{ 
    [[(AppDelegate *)[[UIApplication sharedApplication] delegate] queue] waitUntilAllOperationsAreFinished]; 
    calculating result... 
} 

,仍然被計算之前使用它的結果。所以,我沒有阻止主線程。請幫我做到這一點。

謝謝

回答

4

你不想阻塞主線程;它會阻止用戶使用UI。

你想要的是使用在後臺獲得的結果,一旦準備就緒。

一種方法是在後臺調用該方法的最後調用-use::您定義

-(void)calculate:(NSString*)input 
{ 
    .... do the calculation ... 
    [self performSelectorOnMainThread:@selector(use:) withObject:result]; 
} 

那麼你只需要在主線程中調用

[self performSelectorInBackground:@selector(calculate:) withObject:expression]; 

這樣,您就可以在不阻塞主線程的情況下實現你想要的。

順便說一句,-performSelectorInBackgronudNSOperationQueue無關。所以[queue waitUntilAllOperationsAreFinished]不會等待-performSelectorInBackground調用的方法的執行。 而且無論如何,除非絕對必要,否則請不要撥打waitUntilAllOperationAreFinished

要知道何時NSOperation完成,您KVC的屬性isFinished。請參閱NSOperation reference

+0

我按照你所說的方式做了它,但是在「計算」和「使用」之後,它並沒有回到原來的位置。計算的調用是在一個方法內部完成的,該方法被實現爲該視圖控制器符合的協議的一部分。問題是執行使用後,這種方法不再有效:因此'它沒有回到原來的位置'。 – 2010-05-13 21:54:13

+0

那麼它不會回來,因爲'calculate:'在另一個線程上運行。你需要重新設計你的代碼,以便它能夠工作而不會回到原來的地方。這是背景處理的內在本質,你不能與之對抗。 – Yuji 2010-05-13 22:23:06

0

Yuji有正確的答案,可以阻止你的用戶界面凍結。

但是,如果你真的想想要主線程阻塞,那麼將計算輸出到另一個線程是毫無意義的。只需在主線上完成。即

result = [self calculate: expression]; 

這是保證「阻塞」當前線程,直到它完成。如果在主線程上執行,它將「阻塞」主線程。

+0

在主線程中執行它(因爲它可能需要時間 - 這是關於網絡)阻止我顯示微調。因爲只有在計算結果後纔會顯示。 – 2010-05-13 17:41:09