我希望解析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);
}
由于
答案 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中看到这一点,例如printf
有vprintf
等,而在Cocoa中,-[NSString initWithFormat:]
有-[NSString initWithFormat:arguments:]