2010-10-16 86 views
2

我很努力地找到一種方法來同步iPhone應用程序的操作。 我有三個主要的NSOperation。NSOperation同步問題

NSInvocationOperation *showSpinner = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(spinnerOn:) object:YES]; 
    NSInvocationOperation *reloadDatasource = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(reloadDatasource) object:nil]; 
    NSInvocationOperation *hideSpinner = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(spinnerOn:) object:NO]; 
    // Add dependency 
    [reloadDatasource addDependency:showSpinner]; 
    [hideSpinner addDependency:reloadDatasource]; 

    [self.queue addOperation:showSpinner]; 
    [self.queue addOperation:reloadDatasource]; 
    [self.queue addOperation:hideSpinner]; 

我可以看到三個操作順序正確啓動。然而,正如你可以想象的那樣,第一個操作創建一個UIView並將其附加在頂部,而最後一個應該刪除它。

這種情況發生在圖形上說操作在屏幕上立即發生。所以我可以看到表格已經加載,而微調屏幕上,或其他奇怪的不同步的東西。

我明白圖形端的變化發生在主線程上。所以我問我該如何修改代碼來完成它應該做的事情。這是:創建微調,加載數據,並刪除微調?有沒有一種常見的方法來分離圖形操作和數據操作?例如創建兩個不同的操作。

謝謝

+0

微調控制器最終會被移除還是隻是保持旋轉? hideSpinner操作是否被調用? – twerdster 2010-10-16 13:18:30

+0

從你的描述看來,你實際上需要同步操作......我看到這個錯誤嗎?我的意思是,你可能想要保持reloadDatasource異步,以保持你的Ms和Cs不受你的V(因爲它),但是GUI的東西就像直接的因果關係,是的? – fish2000 2010-10-16 14:21:48

+0

是的,都應該同步發生,包括Views的管理。我只想顯示帶有消息的視圖,如「等待我加載數據」,然後在後臺啓動reloadData中,一旦完成,我想要刪除微調視圖。 – Leonardo 2010-10-16 15:00:28

回答

0

是否必須使用NSOperation?如果不是,那麼我想你正在選擇解決簡單問題的難題,使用NSConnection的委託(或者類似於我不確定你的reloadDataSource做什麼)來啓動和停止微調,然後你是'完成。

1

如何寫

[self spinnerOn:YES]; 
[self performSelectorInBackground:@selector(reloadDatasource) withObject:nil]; 

,然後撥打電話回在「reloadDataSource」的方法你的主線程與

[self performSelectorInMainThread:@selector(spinnerOn:) withObject:NO]; 
+0

這似乎會導致相同的問題,對UI的更改發生與工作流相關的不同步。 – Leonardo 2010-10-16 16:32:13

+0

請您詳細說明它是如何「不同步」的? – tia 2010-10-16 16:43:01

+0

我不得不改變語法,因爲它是錯誤的,還有一些其他的改變,使它的應用程序的方法,使其工作。我的意思是'不同步'是顯示微調,然後重新加載數據,然後最後刪除微調。但是所有的任務應該同步。一個接一個地。我一直認爲NSQueue是最好的同步方式。 – Leonardo 2010-10-18 07:56:06

0

在你spinnerOn:方法,你可以嘗試添加一點邏輯確保操作發生在主線程上?

if (![NSThread isMainThread]) { 
    [self performSelectorOnMainThread:@selector(spinnerOn:) withObject:anObject waitUntilDone:NO]; 
    return; 
} 

我很好奇,看看是否有差別。我的懷疑是,如果你從一個備用線程調用一個UI任務,那麼這些任務就會排隊等候,最終可能會在主線程中稍後未定義的時間內一次性發生。

另一個嘗試的選擇是讓您的操作隊列爲serial隊列。我的意思是一次只能執行一項任務。然後你可以忘記你的依賴關係,因爲它總是會按照你添加它們的順序執行任務。您可以嘗試設置它:

[self.queue setMaxConcurrentOperationCount:1];

讓我知道這是否有幫助。