【发布时间】:2011-10-27 16:15:01
【问题描述】:
我正在尝试使用here 描述的技术构建“假”变量参数列表,但对于启用 ARC 的项目,我无法弄清楚如何摆脱我遇到的错误。
这是有问题的代码:
NSMutableArray* argumentsArray = [NSMutableArray array];
// ... Here I fill argumentsArray with some elements
// And then, I want to construct a "fake" variable argument list
char* fakeArgList = (char*) malloc( sizeof(NSString*) * [argumentsArray count]);
[argumentsArray getObjects: (id*) fakeArgList];
NSString* content = [[NSString alloc] initWithFormat: formatString arguments:fakeArgList];
XCode 抱怨 (id) fakeArgList* 转换,说:
将非 Objective-C 指针类型 'char *' 转换为 '_autoreleasing id *' ARC 不允许使用
我最初的理论是我只需要添加 __unsafe_unretained 到 (id*) 转换告诉 ARC 我负责该内存块并且它不应该保留/释放它,但这不起作用并且我不知道如何解决这个问题。
更新:这是完整的功能。它应该采用 printf 样式的格式字符串和 .plist 中的字段名称变量列表,并输出带有从 .plist 加载的数据的格式化字符串。即,如果我有一个带有字段“field1”=“foo”和“field2”=3 的 .plist 文件并且我调用[loadStringFromFixture: @"?param1=%@&param2=%d", @"field1", @field2],那么我应该得到字符串“?param1=foo¶m2=3”
- (NSString*) loadStringFromFixture:(NSString*) format, ...
{
NSString* path = [[NSBundle mainBundle] bundlePath];
NSString* finalPath = [path stringByAppendingPathComponent:@"MockAPI-Fixtures.plist"];
NSDictionary* plistData = [NSDictionary dictionaryWithContentsOfFile:finalPath];
va_list argumentsList;
va_start(argumentsList, format);
NSString* nextArgument;
NSMutableArray* argumentsArray = [NSMutableArray array];
while((nextArgument = va_arg(argumentsList, NSString*)))
{
[argumentsArray addObject: [plistData objectForKey:nextArgument]];
}
NSRange myRange = NSMakeRange(0, [argumentsArray count]);
id* fakeArgList = (__bridge id *)malloc(sizeof(NSString *) * [argumentsArray count]);
[argumentsArray getObjects:fakeArgList range:myRange];
NSString * content = [[NSString alloc] initWithFormat:formatString
arguments:(__bridge va_list)fakeArgList];
free(fakeArgList);
return content;
}
【问题讨论】:
-
必须有更好的方法来做到这一点......
-
说真的;快速阅读源文章让我认为它只是巧合,超出了 ABI 或规范的范围。
-
没错,但我只需要它用于我的单元测试代码,所以我不太关心它是一个非常“肮脏的黑客”这一事实。虽然如果有人能指出构建变量参数列表的更好方法,我真的很感兴趣。
-
试试
__builtin_va_arg_pack记录在Constructing Calls 中,也许? ARC 始终将对象指针限制为有效或nil。 -
更笼统地说:您应该问一个关于您正在尝试做什么以及如何完成的问题。这是一种方法,但另一种方法可能根本不需要这样做。
标签: objective-c automatic-ref-counting