是否可以对使用变量参数列表的方法使用@selector
和performSelector:
(或类似)?
我正在编写一个可以分配委托的类来覆盖默认行为。在存在委托select方法的情况下,对该类的实例进行的调用将转发到相同的相应委托方法,其中一些方法使用变量参数列表。
因此,例如,我需要能够创建检索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'
}
}
我假设这是不可能的,因此基金会框架中的类似方法声明 - 在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];
我只是想知道我是否遗漏了一些东西,或者想要实现我想要的目标?
答案 0 :(得分:4)
您可以将任何想要的内容传递到运行时函数objc_msgSend
。
objc_msgSend(del, @selector(logEventWithFormat:arguments:), format, argList);
这是发送手动构建的消息的最强大方式。
但是,您不清楚是否需要以这种方式执行调用。正如KennyTM指出的那样,在您拥有的代码中,您可以直接调用该方法。
答案 1 :(得分:2)
您无法使用-performSelector:withObject:withObject:
,因为va_list
根本不是“对象”。您需要使用NSInvocation
。
或者直接致电
[del logEventWithFormat:format arguments:argList];
答案 2 :(得分:2)
据我所知,无法做到。您无法使用-performSelector:withObject:withObject:
,因为@KennyTM指出,va_list
不是对象。
但是,您也无法使用NSInvocation
。 The documentation straight up says so:
NSInvocation不支持 用任何一种方法调用方法 可变数量的参数或联合 参数。
由于这两种方式都是通过选择器调用方法,并且似乎都不起作用,我将继续使用“无法完成”的答案,除非您直接调用该方法并传递{{ 1}}作为一个论点。
也许@bbum会出现并进一步启发我们。 =)
答案 3 :(得分:0)
我之前没有这样做,但我经常使用的简单解决方案是为withObject参数打包/取消装入NSMutableArray或NSMutableDictionary。