我正在尝试构建“假”变量参数列表,使用描述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 * cast,说:
将非Objective-C指针类型'char *'转换为'_autoreleasing id *' 不允许使用ARC
我最初的理论是,我只需要将__unsafe_unretained添加到(id *)转换,告诉ARC我负责该内存块,它不应该保留/释放它,但这不起作用,我无法弄清楚如何解决这个问题。
更新:以下是完整功能。它应该在.plist中采用printf样式的格式字符串和字段名称的变量列表,并输出带有从.plist加载的数据的格式化字符串。即,如果我有一个.plist文件,字段为“field1”=“foo”和“field2”= 3,我调用[loadStringFromFixture: @"?param1=%@¶m2=%d", @"field1", @field2]
然后我应该得到字符串“?param1 = foo& param2 = 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;
}
答案 0 :(得分:1)
看看这段代码,它似乎是一个相当肮脏的黑客,但我想如果它没有ARC,它也应该使用 ARC。这里的问题是你从C指针转向Objective-C指针,你不能没有桥接:
NSMutableArray * argumentsArray = [NSMutableArray array];
// ... Here I fill argumentsArray with some elements
// And then, I want to construct a "fake" variable argument list
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);
这仍然非常难看,我真的希望有更好的方法来做到这一点,但是因为它是用于单元测试,我想它必须这样做。
编辑:可能应该像这样完成桥接演员:
id __autoreleasing * fakeArgList = (__bridge id __autoreleasing *)malloc(sizeof(NSString *) * [argumentsArray count]);