我需要在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/

10-09 16:52