2

是否可以使用@selectorperformSelector:(或类似)使用可变参数列表的方法?

我正在编写一个可以分配一个委托来覆盖默认行为的类。在存在委托的情况下,对该类的实例进行的选择方法调用将转发到相同的相应委托方法,其中一些使用可变参数列表。

因此,例如,我需要能够创建检索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

4 回答 4

4

你可以将任何你想要的东西传递给运行时函数objc_msgSend

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

这是发送手动构建消息的最强大的方式。

但是,尚不清楚您是否需要以这种方式执行调用。正如 KennyTM 所指出的,在您拥有的代码中,您可以直接调用该方法。

于 2010-01-26T08:58:58.157 回答
2

您不能使用-performSelector:withObject:withObject:,因为va_list根本不是“对象”。你需要使用NSInvocation.

或者干脆打电话

[del logEventWithFormat:format arguments:argList];
于 2010-01-26T06:20:52.820 回答
2

据我所知,这是做不到的。您不能使用-performSelector:withObject:withObject:,因为正如@KennyTM 指出的那样, ava_list不是对象。

但是,您也不能使用NSInvocation. 文档直接说:

NSInvocation 不支持使用可变数量的参数或联合参数调用方法。

由于这是通过选择器调用方法的两种方式,而且似乎都不起作用,因此我将选择“无法完成”的答案,除非您直接调用该方法并将va_list作为参数传递。

也许@bbum 会出现并进一步启发我们。=)

于 2010-01-26T07:01:14.677 回答
0

我以前没有这样做过,但我经常使用的简单解决方案是为 withObject 参数装箱/拆箱 NSMutableArray 或 NSMutableDictionary。

于 2010-01-26T06:11:01.820 回答