[英]fake va_list in ARC
我需要在iOS應用程序中創建一個偽va_list
來傳遞給NSString initWithFormat:arguments:
function,這是我的代碼:
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來獲取任意內存塊上的保留/釋放語義 - 它不一定與手頭的問題有關,但它是一個巧妙的小技巧。
作為對未來讀者的一個注意事項:假裝這樣的va_list恰好適用於當前的MacOS和iOS ABI,但總的來說它不是便攜式的,也不是一個好方法。
如果您願意為您的項目添加一點點快速,那么它是可能的!
重要的是NSArray到[CVarArgType]
的映射,它是va_list
的快速等價物。 如果您嘗試將[AnyObject]
為[CVarArgType]
則會導致運行時崩潰,但是使用map
我們可以顯式創建所需的列表。
代碼的其余部分是我制作的包裝器,以便我可以從obj-c調用它。 您可以為要以這種方式調用的任何obj-c函數創建包裝器。
@objc class StringFormat: NSObject {
class func format(key: String, args: [AnyObject]) -> String {
let locArgs: [CVarArgType] = args.map({ (arg: AnyObject) -> CVarArgType in
if let iArg = (arg is NSNumber ? arg.intValue : nil) {
return iArg
}
return arg as! CVarArgType
});
return String(format: key, arguments: locArgs)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.