2010-01-26 73 views
2

是否可以使用@selectorperformSelector:(或類似的)與使用可變參數列表的方法?Objective-C va_list和選擇器

我在寫一個可以分配委託來覆蓋默認行爲的類。在存在委託選擇方法的情況下,對該類的實例進行的調用將轉發給相同的相應委託方法,其中一些使用可變參數列表。

所以,舉例來說,我需要能夠創建檢索SEL參考和消息的方法中的委託對象像這樣:

- (void)logEventWithFormat:(NSString *)format, ... { 
    va_list argList; 
    id del = self.delegate; 
    if (del != nil && 
     [del conformsToProtocol:@protocol(AProtocolWithOptionalMethods)] && 
     [del respondsToSelector:@selector(logEventWithFormat:)]) 
    { 
     // Perform selector on object 'del' with 'argList' 
    } 
} 

我假定這是不可能的,因此,類似的方法聲明Foundation框架 - 在NSString

- (id)initWithFormat:(NSString*)format, ...; 

- (id)initWithFormat:(NSString *)format arguments:(va_list)argList; 

我假設我希望協議委託給應建議的落實:

- (void)logEventWithFormat:(NSString *)format arguments:(va_list)argList; 

所以我選擇@selector(logEventWithFormat:arguments:)可以使用調用:

[del performSelector:@selector(logEventWithFormat:arguments:) 
      withObject:format 
      withObject:argList]; 

我,如果我想知道錯過了什麼或者走了很長的路要實現我想要的?

回答

4

你可以將任何你想要的東西傳入運行時功能objc_msgSend

objc_msgSend(del, @selector(logEventWithFormat:arguments:), format, argList); 

這是發送手動構建消息的最有效方式。

但是,您不清楚您是否需要以這種方式執行調用。正如KennyTM所指出的那樣,在您擁有的代碼中,您可以直接調用該方法。

0

我還沒有這樣做過,但我經常使用的簡單解決方案是爲withObject參數box/unbox或NSMutableArray或NSMutableDictionary。

2

您不能使用-performSelector:withObject:withObject:,因爲va_list根本不是「對象」。您需要使用NSInvocation

或直接致電

[del logEventWithFormat:format arguments:argList]; 
+0

'NSInvocation'不起作用。文件說明如此。 – 2010-01-26 07:03:00

+2

@Dave:如果您將'va_list'作爲參數傳遞('ObjC運行時「中的'va_list'等價於'void *'),'NSInvocation' *將會工作。你不能將任意多個參數傳遞給'-stringWithFormat:'帶'NSInvocation',因爲類型簽名省略了'...'部分。 – kennytm 2010-01-26 07:13:55

2

據我所知,它不能這樣做。你不能使用-performSelector:withObject:withObject:,因爲@KennyTM指出,va_list不是一個對象。

但是,您也不能使用NSInvocationThe documentation straight up says so:

NSInvocation的不支持與參數要麼 變量的數字或工會 參數的方法 調用。

由於這些是通過選擇器調用方法的兩種方式,而且都不起作用,所以我會去用「無法完成」的答案,除非直接調用方法並傳遞作爲論點的va_list

也許@bbum會出現並進一步啓發我們。 =)

+1

'-forwardInvocation:'爲需要可變數量參數的方法調用,提供的'NSInvocation'似乎有效,與文檔相反。至少,我能夠通過'-performSelector:onThread:withObject:waitUntilDone:'成功調用' - [NSInvocation invoke]'。 – lemnar 2011-07-05 18:26:23

+0

@lemnar很高興知道,謝謝 – 2011-07-05 18:44:44

+0

原來,只有在少於五個對象參數的情況下調用纔會發生:https://gist.github.com/1941795 – lemnar 2012-03-07 13:15:06