2010-06-28 71 views
0

我已經定義了一個協議是這樣的:發送委託方法異步 - iPhone

@protocol RSSItemParserDelegate <NSObject> 
- (void)RSSItemParser:(RSSItemParser *)parser 
didEndParsingSuccesfully:(BOOL)success; 
@end 

我打電話來時,一些分析完成這種方法,成功YES,失敗NO,像這樣:

[delegate RSSItemParser:self didEndProcessSuccesfully:NO]; 

但我想它在異步運行在主線程。我怎樣才能做到這一點?

我認爲performSelectorOnMainThread:withObject:waitUntilDone:可以用一個唯一的參數方法工作,但如何使用兩個參數如礦的方法? 特別是在使用AVFoundation和CoreVideo時,有很多代表方法有兩個以上的參數,我不知道它們是如何調用的。

感謝

伊格納西奧

回答

2
SEL action = @selector(actionWithFoo:bar:baz:); 
NSInvocation * i = [NSInvocation invocationWithMethodSignature:[target methodSignatureForSelector:action]]; 
[i retainArguments]; 
[i setTarget:target]; 
[i setAction:action]; 
[i setArgument:&foo atIndex:2]; 
[i setArgument:&bar atIndex:3]; 
[i setArgument:&baz atIndex:4]; 
[i performSelectorOnMainThread:@selector(invoke) withObject:nil waitUntilDone:NO]; 

僅僅使用字典就簡單多了,可擴展性也好。

+0

這是使用NSInvocation的一個很好的例子,非常適合我的需求。謝謝;) – nacho4d 2010-06-29 06:24:27

1

有很多方法可以做到這一點。您可以使用NSInvocation API創建一個調用對象,然後使用其中一個performSelector...方法(因爲invoke及其親屬取0或1個參數)。或者,您可以創建一個內部包裝方法,該方法採用一個「上下文」對象(一個結構或字典)來包裝所有需要傳遞給委託的值。然後,在主線程上執行該方法並解壓上下文值以將它們傳遞給實際的委託方法。或者,您可以直接將上下文對象傳遞給您的代理,並讓它進行拆箱。

+0

謝謝,你能舉個例子嗎?我可能會誤解這個,但我認爲它類似於draonward的答案,只是它使用NSInvocation。 – nacho4d 2010-06-28 07:35:47

0

簡單的方法是創建一個只需要一個參數的方法。在你的情況下,做一個委託調用方法:

-(void) invokeDelegateWithDidEndProcessSuccesfully:(NSNumber)success { 
    [delegate RSSItemParser:self didEndProcessSuccesfully:[success boolValue]]; 
} 

然後使用它:

-(void) didEndParsingSuccesfully:(BOOL)success { 
    [self performSelectorOnMainThread:@selector(invokeDelegateWithDidEndProcessSuccesfully) withObject:[NSNumber numberWithBool:success] waitUntilDone:NO]; 
} 

難的方法是使用NSInvocation的處理的參數任意數量。沒有任何論點是隱含保留的。

+0

謝謝你的回答,這實際上是我現在正在做的。但我認爲應該有一個更「優雅」或「正確」的方式來做到這一點。 – nacho4d 2010-06-28 07:36:10