我从以下行获取“格式字符串不是字符串文字”警告
NSString *formattedString = [[NSString alloc] initWithFormat:format arguments:valist];
我在以下功能中使用它
- (void)logMessage:(NSString *)format
level:(LoggingLevel)level
withParameters:(va_list)valist {
if (level >= self.loggingLevel) {
NSString *formattedString = [[NSString alloc] initWithFormat:format arguments:valist];
}
知道怎么解决这个问题吗?我正在使用Xcode 4.6.3
答案 0 :(得分:10)
使用以下方法取消它:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"
- (void)logMessage:(NSString *)format
level:(LoggingLevel)level
withParameters:(va_list)valist {
if (level >= self.loggingLevel) {
NSString *formattedString = [[NSString alloc] initWithFormat:format arguments:valist];
}
#pragma clang diagnostic pop
答案 1 :(得分:10)
如果你告诉编译器你的方法有类似格式的参数,请使用
NS_FORMAT_FUNCTION
宏:
- (void)logMessage:(NSString *)format
level:(LoggingLevel)level
withParameters:(va_list)valist NS_FORMAT_FUNCTION(1,0) {
if (level >= self.loggingLevel) {
NSString *formattedString = [[NSString alloc] initWithFormat:format arguments:valist];
}
}
然后
示例:
NSString *abc = @"foo %@ bar";
[self logMessage:abc level:7 withParameters:NULL];
warning: format string is not a string literal [-Wformat-nonliteral]
[self logMessage:abc level:7 withParameters:NULL];
^~~
已添加:这同样适用于评论中提到的功能。
它们也应该使用NS_FORMAT_FUNCTION
“标记”:
+ (void)logVeryFineWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2)
{
va_list ap;
va_start(ap, format);
[[self sharedInstance] logMessage:format level:VERY_FINE withParameters:ap];
va_end(ap);
}
+ (void)say:(NSString *)formatstring, ... NS_FORMAT_FUNCTION(1,2)
{
va_list arglist;
va_start(arglist, formatstring);
// This is not needed:
// NSString *litralString = [NSString stringWithFormat:@"%@",formatstring];
NSString *statement = [[NSString alloc] initWithFormat:formatstring arguments:arglist];
va_end(arglist);
[ModalAlert ask:statement withCancel:@"Okay" withButtons:nil];
}
答案 2 :(得分:0)
格式字符串应该是@“某些格式说明符要被varargs替换”,就像在stringWithFormat中一样:或在NSLog中
请记住@在Objective-C中到处都有特殊含义。它是一个指示编译器指令的符号。编译器将知道如何处理以下令牌(扩展它或转换内容,有时寻找匹配的配对指令,如@end
答案 3 :(得分:-1)
正如@trojanfoe建议的那样,对你来说,抑制警告可能是正确的解决办法。只是警告是有原因的。
如果您的格式字符串与参数的数量和/或类型不匹配,则应用程序可能会在运行时中断。当您将格式提供为字符串文字,例如@“我的输出是:%@”时,您可以使编译器检查参数的类型和数量。
使用字符串变量作为格式可能有充分的理由。但是,在这种情况下,当涉及到避免此类错误时,您就可以独立完成。
无论如何,我建议重新考虑你的算法,而不是使用字符串文字。