解析 Class 类型的可变参数列表

Parse varargs list of type Class

我想解析 iOS Objective-C 中 Class 类型的参数列表。每当我尝试解析列表时,我目前都会收到 EXEC_BAD_ACCESS 。这是解析列表的实现。

#import <Foundation/Foundation.h>

@interface NSArray (Args)

+ (NSArray *)arg_fromArgs:(id)clazz, ... NS_REQUIRES_NIL_TERMINATION;

@end

#import "NSArray+Args.h"

@implementation NSArray (Args)

+ (NSArray *)arg_fromArgs:(id)clazz1, ... {
    NSMutableArray *arguments = [NSMutableArray new];

    id eachObject;
    va_list argumentList;
    if (clazz1)
    {
        [arguments addObject:clazz1];
        va_start(argumentList, clazz1);
        while ((eachObject = va_arg(argumentList, id)))
        {
            [arguments addObject: eachObject];
        }
        va_end(argumentList);
    }

    return [NSArray arrayWithArray:arguments];
}

@end

while ((eachObject = va_arg(argumentList, id))) 行是我访问错误的地方。我是这样称呼它的:

NSArray *classes = [NSArray arg_fromArgs:[Class1 class], [Class2 class], [Class3 class], nil];

我已经尝试将 id 变量更改为 Class,但仍然没有任何作用。关于如何实现这一点的任何想法(除了直接在我的方法中传递一个 类 数组)?

注意:此崩溃仅发生在物理设备上。它在模拟器上运行得非常好。

提前致谢

编辑

根据newacct的建议,我是这样解决的。有没有办法不用通过第一个Class?

+ (NSArray *)arg_fromClass:(Class)clazz andArgsList:(va_list)argumentList {
    NSMutableArray *arguments = [NSMutableArray new];
    [arguments addObject:clazz];

    id eachObject;
    while ((eachObject = va_arg(argumentList, id)))
    {
        [arguments addObject: eachObject];
    }
    va_end(argumentList);

    return [NSArray arrayWithArray:arguments];
}

我怎么称呼它。

- (void)someMethod:(Class)clazz, ... {
    va_list argumentList;
    va_start(argumentList, clazz);
    NSArray *classesToSync = [NSArray arg_fromClass:clazz andArgsList:argumentList];

    NSLog(@"Syncing Classes: %@", classesToSync);
}

谢谢

我查看了您发布的示例应用程序。您的 +[NSArray arg_fromClassArgs:] 方法没有任何问题。它是一个可变参数方法,需要可变数量的对象指针参数,末尾有一个 nil 参数。

问题是您在 +[ArgReceiver convertArgsToArray:] 方法中这样调用此方法:

[NSArray arg_fromClassArgs:args]

你传递了一个参数,末尾没有 nil 个参数。

你的 +[ArgReceiver convertArgsToArray:] 方法的编写方式(它本身是一个可变参数方法,它接受可变数量的参数,第一个你命名为 args)似乎表明你旨在 "pass off" 从该方法到另一个可变参数方法的变量参数。但这是不可能的——在 C 中,没有标准的方法可以让一个可变参数函数将它的参数传递给另一个可变参数函数。

唯一的方法是有一个单独版本的 +[NSArray arg_fromClassArgs:] 方法,它接受一个 va_list 参数(可能称之为 +[NSArray arg_fromClassArgsVaList:] 或其他东西),用于其他可变参数方法调用(并且 +[NSArray arg_fromClassArgs:] 本身可以调用,因此您没有重复的代码)。你可以在C中看到这个API,例如printfvprintf等,而在Cocoa,-[NSString initWithFormat:]-[NSString initWithFormat:arguments:]