我需要在iOS应用程序中创建一个假va_list
传递给NSString initWithFormat:arguments:
函数,这是我的代码:
NSArray *fixedArguments = [[NSArray alloc] initWithArray:arguments];
NSRange range = NSMakeRange(0, [fixedArguments count]);
va_list fakeArgList = (va_list)malloc(sizeof(NSString *) * [fixedArguments count]);
__unsafe_unretained id *ptr = (__unsafe_unretained id *)fakeArgList;
[fixedArguments getObjects:ptr range:range];
content = [[NSString alloc] initWithFormat:outputFormat
arguments:(va_list)fakeArgList];
free(fakeArgList);
编译器在强制转换行中提示此消息:
error: cast of a non-Objective-C pointer type 'va_list' (aka 'char *') to '__unsafe_unretained id *' is disallowed with ARC
getObjects:range:
函数的定义如下:- (void)getObjects:(id __unsafe_unretained [])objects range:(NSRange)range;
我已经尝试了一切,但仍然无法摆脱此错误...
是否有解决方案,可以在启用ARC的情况下创建伪造的
va_list
?我究竟做错了什么? 最佳答案
编辑:这不再起作用。如最初答案中所预见的那样,ABI似乎已从该答案的下方更改了
玩了一会儿,让它正常工作-仔细检查了泄漏或废弃的内存,没有看到任何东西。
NSArray *fixedArguments = [[NSArray alloc] initWithObjects: @"foo", @"bar", @"baz", nil];
NSRange range = NSMakeRange(0, [fixedArguments count]);
NSMutableData* data = [NSMutableData dataWithLength: sizeof(id) * [fixedArguments count]];
[fixedArguments getObjects: (__unsafe_unretained id *)data.mutableBytes range:range];
NSString* content = [[NSString alloc] initWithFormat: @"1: %@ 2: %@ 3: %@" arguments: data.mutableBytes];
NSLog(@"%@", content);
我喜欢(ab)这样使用NSMutableData在任意内存块上获取保留/释放语义-不一定与当前问题相关,但这是一个巧妙的小技巧。
作为对 future 读者的说明:伪造这样的va_list可以与当前适用于MacOS和iOS的ABI一起使用,但是总的来说,它不是可移植的,也不是一种很好的方法。
关于objective-c - ARC中的伪造va_list,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8211996/