NSLog和NSLogv之间的区别

Siv*_*ami 7 objective-c nslog swift

任何人都可以解释NSLog和NSLogv之间的区别吗?我知道NSLog用于在控制台中打印数据.但是什么NSLogv呢?

jtb*_*des 11

假设您要编写类似于 NSLog 的函数,但除了记录它之外,还会将消息保存到数组中.你会如何实现这个?

如果你写一个可变参数函数 void MySpecialLog(NSString *format, ...),有人可以打电话给你的功能就像NSLog的- MySpecialLog(@"Hello %@!", name);-但访问超出了额外的参数的唯一方法format是用一个va_list.C或Obj-C中没有splat操作符允许您将它们直接传递给函数内部的NSLog.

NSLogv通过一次接受所有附加参数来解决这个问题va_list.它的签名是void NSLogv(NSString *format, va_list args).您可以使用它来构建自己的 NSLog包装器.

OBJ-C

void MySpecialLog(NSString *format, ...)
  NS_FORMAT_FUNCTION(1, 2)
    // The NS_FORMAT_FUNCTION attribute tells the compiler to treat the 1st argument like
    // a format string, with values starting from the 2nd argument. This way, you'll
    // get the proper warnings if format specifiers and arguments don't match.
{
    va_list args;
    va_start(args, format);

    // Do something slightly more interesting than just passing format & args through...
    NSString *newFormat = [@"You've called MySpecialLog()! " stringByAppendingString:format];

    NSLogv(newFormat, args);

    va_end(args);
}
Run Code Online (Sandbox Code Playgroud)

您甚至可以使用相同的技术使用Obj-C方法包装NSLog.(因为-[NSString initWithFormat:]有一个类似的变体叫-initWithFormat:arguments:,你也可以包装它.)

- (void)log:(NSString *)format, ... NS_FORMAT_FUNCTION(1, 2)
{
    // Similarly to the above, we can pass all the arguments to -initWithFormat:arguments:.
    va_list args;
    va_start(args, format);
    NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
    va_end(args);

    // Why not both?
    va_start(args, format);
    NSLogv(format, args);
    va_end(args);
}
Run Code Online (Sandbox Code Playgroud)

迅速

在Swift中,您可以使用可变参数函数来接受CVarArg...:

func mySpecialLog(_ format: String, _ args: CVarArg...) {
    withVaList(args) {
        NSLogv("You've called mySpecialLog()! " + format, $0)
    }
}
Run Code Online (Sandbox Code Playgroud)