解析类型Class的varargs列表

时间:2016-05-11 16:11:16

标签: ios variadic-functions

我希望解析iOS Objective-C中类型为Class的args列表。每当我尝试解析列表时,我正在获得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的建议解决的问题。有没有办法不必通过第一堂课?

+ (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);
}

由于

1 个答案:

答案 0 :(得分:1)

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

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

[NSArray arg_fromClassArgs:args]

你传递一个参数,最后没有nil参数。

你的+[ArgReceiver convertArgsToArray:]方法的编写方式(它本身是一个varargs方法,它采用可变数量的参数,第一个你命名为args)似乎表明你打算将该方法中的变量参数“传递”到另一个varargs方法。但这是不可能的 - 在C中没有标准的方法让varargs函数将其参数传递给另一个varargs函数。

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