fake va_list in ARC

孤人 提交于 2019-11-27 14:02:05

EDIT: This no longer works. As foreseen in the initial answer, the ABI appears to have changed out from under this answer

Played around for a bit and got it to work -- Double checked for leaks or abandoned memory and didn't see any.

    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);

I like to (ab)use NSMutableData like this to get retain/release semantics on an arbitrary chunk of memory -- It's not necessarily relevant to the issue at hand, but it's a neat little trick.

As a note to future readers: Faking up a va_list like this happens to work with the current ABI for MacOS and iOS, but in general it's not portable, and not a good approach.

Its possible if you are willing to add a little bit of swift to your project!

The important bit is the mapping of NSArray to [CVarArgType] which is the swift equivalent for va_list. If you try to cast [AnyObject] to [CVarArgType] you cause run time crashes, but with the map we can explicitly make the needed list.

The rest of the code is the wrapper I made so that I can call this from obj-c. You could make a wrapper for any obj-c function that you want to call in this way.

@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)
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!