I'm trying to construct "fake" variable arguments list, using the technique described here, but for ARC-enabled project and I can't figure out how to get rid of the error I'm getting.
Here's the code in question:
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 complains on the (id) fakeArgList* casting, saying:
Cast of non-Objective-C pointer type 'char *' to '_autoreleasing id *' is disallowed with ARC
My initial theory was that I just need to add __unsafe_unretained to (id*) casting to tell ARC that I'm responsible for that block of memory and it shouldn't retain/release it, but that doesn't work and I can't figure out how to fix this problem.
Update: Here's the full function. It should take a printf-style format string and a variable list of field names inside the .plist and output a formatted string with data loaded from .plist. I.e., if I have a .plist file with fields "field1" = "foo" and "field2" = 3 and I call [loadStringFromFixture: @"?param1=%@¶m2=%d", @"field1", @field2]
then I should get string "?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;
}
__builtin_va_arg_pack
documented in Constructing Calls, maybe? ARC restricts object pointers to be either valid ornil
at all times. – Jeremy W. Sherman