2010-01-17 52 views
1

考慮一下:如何從NSOperationQueue啓動的線程優化回調

@interface SomeViewController : UIViewController { 
    SomeChildObject *child; 
} 
@end 

@implementation SomeViewController 

- (void) viewDidLoad { 
    ... 
    child.delegate = self; 
} 

- (void) somethingHappened { 
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] 
     initWithTarget:child 
     selector:@selector(doSomething) 
     object:nil]; 
[someNsOperationQueue addOperation:operation]; 
[operation release]; 
} 

- (void) callbackA:(SomeData *)someData { 
[self performSelectorOnMainThread:@selector(callbackAonMainThread:) 
         withObject:someData 
        waitUntilDone:NO]; 
} 

- (void) callbackAonMainThread:(SomeData *)someData { 
    ... do something with results in main thread, e.g UI feedback 
} 

- (void) callbackB:(SomeData *)someData { 
[self performSelectorOnMainThread:@selector(callbackBonMainThread:) 
         withObject:someData 
        waitUntilDone:NO]; 
} 

- (void) callbackBonMainThread:(SomeData *)someData { 
    ... do something with results in main thread, e.g UI feedback 
} 


@end 

英文:

我有一個子模型對象做一些主線程運行的視圖控制器(取網絡數據)。視圖控制器是孩子的代表,所以孩子可以通過委派來發回結果。爲了執行昂貴的工作,我使用NSInvocationOperation生成child.doSomething方法,該方法在後臺線程中啓動該操作。完成後,孩子用一些結果調用委託的(視圖控制器)callbackA或callbackB。因爲(我認爲)這些回調是在doSomething調用運行的同一後臺線程中調用的,所以我需要調用performSelectorOnMainThread將控制權轉移回主線程。

這很好,但我不喜歡每個回調有兩個回調相關的方法。 (實際上有更多的回調,所以真正的代碼更加臃腫。)理想情況下,我會做這樣的事情:

- (void) callbackA:(SomeData *)someData { 
    if (not_running_on_main_thread) { 
    [self performSelectorOnMainThread:@selector(callbackA:) 
         withObject:someData 
        waitUntilDone:NO]; 
    } else { 
     // now running on main thread, work with the results. 
    } 
} 

問題:

1)我該怎麼做「not_running_on_main_thread」測試?

2)有沒有其他的方法來減少回調膨脹?

編輯:好吧,我從來沒有閱讀NSThread文檔發佈之前:)看起來像[NSThread isMainThread]是我正在尋找。但是有沒有其他的方式來重組或使這個更好?

回答

6

只需檢查[NSThread isMainThread]。如果你需要多個回調來完成不同的事情,那麼你就無能爲力了。

只有一件事我有什麼不同,我的代碼看起來是這樣的:

- (void) callbackA:(SomeData *)someData { 
    if (![NSThread isMainThread]) { 
     [self performSelectorOnMainThread:@selector(callbackA:) 
         withObject:someData 
        waitUntilDone:NO]; 
     return; 
    } 

    // now running on main thread, work with the results. 
} 

這讓我擺脫了全功能的長else的,使代碼更清晰一點。並且您可以用這種方式在一個縮進級別上保存;-)

+0

好的退貨提示。我喜歡漂亮的代碼。 – Jaanus 2010-01-17 16:37:07