objective-c - 警告 : "format not a string literal an

自从升级到最新的 Xcode 3.2.1 和 Snow Leopard 后,我一直收到警告

"format not a string literal and no format arguments"

来自以下代码:

NSError *error = nil;

if (![self.managedObjectContext save:&error]) 
{
    NSLog([NSString stringWithFormat:@"%@ %@, %@", 
       errorMsgFormat, 
       error, 
       [error userInfo]]);      

}

如果 errorMsgFormat 是带有格式说明符的 NSString(例如:"print me like this: %@"),有什么问题上面的 NSLog 调用?以及建议的修复方法是什么,以便不生成警告?

最佳答案

Xcode 提示,因为这是一个安全问题。

这里的代码与你的类似:

NSString *nameFormat = @"%@ %@";
NSString *firstName = @"Jon";
NSString *lastName = @"Hess %@";
NSString *name = [NSString stringWithFormat:nameFormat, firstName, lastName];
NSLog(name);

最后一个 NSLog 语句将执行相当于这个:

NSLog(@"Jon Hess %@");

这将导致 NSLog 再寻找一个字符串参数,但没有。由于 C 语言的工作方式,它会从堆栈中取出一些随机垃圾指针,并尝试将其视为 NSString。这很可能会使您的程序崩溃。现在您的字符串中可能没有 %@,但有一天它们可能会出现。您应该始终使用带有您明确控制的数据的格式字符串作为采用格式字符串(printf、scanf、NSLog、-[NSString stringWithFormat:]、...)的函数的第一个参数。

正如 Otto 指出的那样,您可能应该这样做:

NSLog(errorMsgFormat, error, [error userInfo]);

关于objective-c - 警告 : "format not a string literal and no format arguments",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1677824/

相关文章:

objective-c - 从 iOS 上的 UIView 将图像保存到应用程序文档文件夹

ios - Xcode MyProjectName-Bridging-Header.h 不存在

objective-c - 如何在 Objective-C 中复制对象

iphone - Objective C中变量位置的声明/定义?

objective-c - 最佳实践 - 您自己的项目/应用程序的 NSError 域和代码

ios - 从文档目录中删除指定文件

iphone - 以编程方式请求访问联系人

objective-c - 何时使用 -retainCount?

ios - Xcode 9 中的 "This function declaration is not

iphone - Apple 怎么知道你在使用私有(private) API?