简体   繁体   English

Objective-C va_list和选择器

[英]Objective-C va_list and selectors

Is it possible to use @selector and performSelector: (or similar) with methods using variable arguments list? 是否可以使用@selectorperformSelector:或类似)与使用变量参数列表的方法?

I'm writing a class that can be assigned a delegate to override the default behavior. 我正在编写一个可以分配委托的类来覆盖默认行为。 In the presence of a delegate select method calls made on an instance of that class will be forward to the same corresponding delegate method, some which use variable argument lists. 在存在委托select方法的情况下,对该类的实例进行的调用将转发到相同的相应委托方法,其中一些方法使用变量参数列表。

So, for instance, I need to be able to create retrieve SEL reference and message the delegate object with a method such as this: 因此,例如,我需要能够创建检索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'
    }
}

I am assuming this is not possible, hence the similar method declaration in the Foundation framework - in NSString : 我假设这是不可能的,因此在Foundation框架中类似的方法声明 - 在NSString

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

and

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

I assume that the protocol I wish to delegate to should suggest the implementation of: 我假设我希望委托的协议应该建议实施:

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

so I the selector @selector(logEventWithFormat:arguments:) can be used an called with: 所以我的选择器@selector(logEventWithFormat:arguments:)可以用来调用:

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

I just wondered if I was missing something or going the long way around to achieve what I'm trying to? 我只是想知道我是否遗漏了一些东西,或者想要实现我想要的目标?

You can pass anything you want into the runtime function objc_msgSend . 您可以将任何想要的内容传递给运行时函数objc_msgSend

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

It's the most powerful way of sending a manually constructed message. 这是发送手动构造的消息的最有效方式。

However, it's not clear that you need to perform the invocation this way. 但是,您不清楚是否需要以这种方式执行调用。 As KennyTM pointed out, in the code you have, you could invoke the method directly. 正如KennyTM指出的那样,在您拥有的代码中,您可以直接调用该方法。

You can't use -performSelector:withObject:withObject: because va_list simply isn't an "object". 您不能使用-performSelector:withObject:withObject:因为va_list根本不是“对象”。 You need to use NSInvocation . 您需要使用NSInvocation

Or simply call 或者直接打电话

[del logEventWithFormat:format arguments:argList];

As far as I know, it can't be done. 据我所知,它无法完成。 You can't use -performSelector:withObject:withObject: because as @KennyTM points out, a va_list isn't an object. 你不能使用-performSelector:withObject:withObject:因为@KennyTM指出, va_list不是一个对象。

However, you also cannot use NSInvocation . 但是,您也无法使用NSInvocation The documentation straight up says so: 直截了当的文件说:

NSInvocation does not support invocations of methods with either variable numbers of arguments or union arguments. NSInvocation不支持使用可变数量的参数或联合参数调用方法。

Since these are the two ways of invoking a method by selector, and neither seems to work, I'm going to go with the "can't be done" answer, unless you invoke the method directly and pass the va_list as an argument. 由于这两种方式是通过选择器调用方法,并且似乎都不起作用,我将继续使用“无法完成”的答案,除非您直接调用该方法并将va_list作为参数传递。

Perhaps @bbum will show up and enlighten us further. 也许@bbum会出现并进一步启发我们。 =) =)

我之前没有这样做,但我经常使用的简单解决方案是为withObject参数打包/取消装入NSMutableArray或NSMutableDictionary。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM