警告:“不格式化字符串文字,不格式化参数”

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


“不格式化字符串文字,不格式化参数”


从以下代码中:


NSError *error = nil;


if (![self.managedObjectContext save:&error]) 

{

    NSLog([NSString stringWithFormat:@"%@ %@, %@", 

       errorMsgFormat, 

       error, 

       [error userInfo]]);      


}

如果errorMsgFormat是NSString带有格式说明符(例如"print me like this: %@":),那么上述NSLog调用有什么问题?推荐的解决方法是什么,以便不生成警告?


慕田峪9158850
浏览 619回答 3
3回答

小怪兽爱吃肉

您是否正确嵌套了括号?我不NSLog()喜欢只接受一个论点,这就是您要通过的论点。另外,它已经为您完成了格式化。为什么不这样做呢?NSLog(@"%@ %@, %@",    errorMsgFormat,    error,    [error userInfo]);              或者,由于您说的errorMsgFormat是带有单个占位符的格式字符串,您是否要这样做?NSLog(@"%@, %@", [NSString stringWithFormat:errorMsgFormat, error],    [error userInfo]);              

阿晨1998

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

慕仙森

最终答案:正如乔恩·赫斯(Jon Hess)所说,这是一个安全问题,因为您要将WHATEVER字符串传递给需要格式字符串的函数。也就是说,它将评估任何字符串内的所有格式说明符。如果没有,那太棒了,但是如果有,那么可能会发生坏事。那么,正确的做法是直接使用格式字符串,例如NSLog(@"%@", myNSString);这样,即使myNSString中有格式说明符,它们也不会被NSLog评估。
打开App,查看更多内容
随时随地看视频慕课网APP