2011-05-25 68 views
9

好吧,所以說我有第二個線程運行,但它想要操縱主線程上的東西,如UI項目。通過performSelectorOnMainThread傳遞原語

-(void)backgroundThread 
{ 
    [myButton performSelectorOnMainThread:@selector(setEnabled:) withObject:(BOOL)YES waitUntilDone:YES]; 
    // right here, how could i pass this BOOL to the function 
} 

我一直在使用NSNumbernumberWithBOOL試過,但NSButton不接受它。

回答

14

您不能使用performSelectorOnMainThread:withObject:waitUntilDone:的參數不是Objective-C對象,並且不能使用NSNumber,因爲沒有從對象到原始類型的自動拆箱。

一種解決方案是實現一種類似的方法,它接受一個按鈕作爲參數並改爲調用該方法。

例如,在相同的類:

- (void)enableButton:(NSButton *)button { 
    [button setEnabled:YES]; 
} 

-(void)backgroundThread{ 
    [self performSelectorOnMainThread:@selector(enableButton:) 
          withObject:myButton 
         waitUntilDone:YES]; 
} 

另一種解決方案是實現上NSButton一個類別具有替代方法(例如-setEnabledWithNumber:),和使用該方法改爲:

@interface NSButton (MyButtonCategory) 
- (void)setEnabledWithNumber:(NSNumber *)enabled; 
@end 

@implementation NSButton (MyButtonCategory) 
- (void)setEnabledWithNumber:(NSNumber *)enabled { 
    [self setEnabled:[enabled boolValue]]; 
} 
@end 

-(void)backgroundThread{ 
    [myButton performSelectorOnMainThread:@selector(setEnabledWithNumber:) 
           withObject:[NSNumber numberWithBool:YES] 
          waitUntilDone:YES]; 
} 
+0

雅,我已經實施了第二種方法,但類別的想法更好 – 2011-05-25 07:14:24

3

你可以使用塊:

BOOL boolValue = YES; 

[self performOnMainThreadWait:YES block:^(id owner) { 
    [button setEnabled:boolValue]; 
}]; 

這裏使用了我的執行延遲塊:

@implementation NSObject (HHBlockPerform) 

- (void)performAfterDelay:(NSTimeInterval)delay block:(HHPerformBlock)block 
{ 
    [self performSelector:@selector(runBlock:) withObject:[block copy] afterDelay:delay]; 
} 

- (void)performOnMainThreadWait:(BOOL)wait block:(HHPerformBlock)block 
{ 
    [self performSelectorOnMainThread:@selector(runBlock:) 
          withObject:[block copy] 
         waitUntilDone:wait 
           modes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; 
} 

- (void)runBlock:(HHPerformBlock)block 
{ 
    block(self); 

    [block release]; 
} 

@end 
+0

什麼是一個塊,它用於什麼?如果你可以提供一個鏈接,那會很有幫助。 – 2011-05-25 08:35:51

+0

http://thirdcog.eu/pwcblocks/ – 2011-05-25 20:00:04

+0

謝謝,這很有幫助 – 2011-05-26 23:05:15

3

是的,performSelectorOnMainThread:withObject:waitUntilDone:不再適用於所有基本類型。在過去,只要你只有一個參數,它就可以工作,並且它是一個整體類型,可以無損地轉換成指針。這是不安全的,它不漂亮,但它確實工作。

但是,Apple最近更改了這些方法的實現,以保留+釋放它們的參數,當參數包含BOOL或其他非對象類型時,這顯然會炸燬。

雖然我已經創建了一個過去的輔助方法,我最喜歡的技術現在是使用Higher Order Message如下列:

[[myButton onMainThread] setEnabled:YES]; 

在HOM的執行中使用的NSInvocation需要包裝的關懷和解開所有的基本類型,並且HOM語法可以很容易地輸入和清除。

我稱這種技術爲Little Message Dispatch