如何使用带有“未使用变量”警告的类型常量?

我正在使用Xcode 4.6,我有一个头文件,其中包含我在整个代码中使用的一些常量。 我不想使用预处理程序指令,因为我希望它们能够正确输入等等。

例如,我在我的一个.h文件中有这个代码:

static NSString *kErrorCannotDivideByZero = @"Error: Cannot divide by zero"; 

我在相应的.m文件中使用它:

 [self showToast:kErrorCannotDivideByZero]; 

我收到警告:

 /path/to/my/headerFile.h:32:18: Unused variable 'kErrorCannotDivideByZero' 

我知道这只是一个警告,但我有大约50个这些警告堵塞了我的编译器输出。

为什么我收到此警告以及如何正确解决此问题?

我对简单地压制所有未使用的变量警告并不感兴趣,因为我确实希望得到合法的警告。

在标题extern声明,而不是static 。 你正在做的是为包含你的标题的每个翻译单元创建一个变量,这就是Clang警告你的原因,因为它合法地是一个未被使用的定义变量。 extern关键字告诉编译器变量的定义是在其他地方找到的(它可能在同一个翻译单元中,也可能在另一个中)。

在标题中,有:

 // declare that the constant exists somewhere extern NSString * const kErrorCannotDivideByZero; 

在你的一个.m文件中(通常是与标题共享同名的文件),put

 // define the constant, ie this is where it exists NSString * const kErrorCannotDivideByZero = @"Error: Cannot divide by zero"; 

声明变量extern允许编译器确保您正确处理变量,即使它不知道它的定义位置(例如,您不能将其用作NSArray )。 链接器的工作是确保您实际在某处定义它。

Clang将允许您在“诊断”堆栈上推送和弹出警告标志: “通过编译指示控制诊断” 。 你可以像这样包装某些代码片段:

 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-variable" static NSString *kErrorCannotDivideByZero = @"Error: Cannot divide by zero"; #pragma clang diagnostic pop 

告诉Clang你知道这些没用过,在这个特殊的例子中没关系。

顺便提一下,您可能不希望在导入到许多不同位置的文件中定义这些变量 – 这是导致变量重定义的链接器错误的好方法(尽管只有在变量全局链接时才会发生这种情况 – 声明/定义没有 static )。 像这样的常量的通常模式是在标题中放置一个extern 声明 ,并在另一个文件中定义该变量。 有关详细信息,请参阅从另一个类引用静态NSString * const 。

正如dreamlax指出的那样,你实际上得到了这些警告,因为导入你的头文件的每个文件都获得了自己的static变量副本; 当我提出上面的#pragma技术时,我误解了你的要求。

使你的常量const

 static NSString * const kErrorCannotDivideByZero = @"Error: Cannot divide by zero"; 

(和其他人指出的那样,在实现文件中使用extern和define)

也许,不是将它们初始化为字符串文字,而是可以运行初始化函数,该函数从特定于语言环境的文件加载这些值,以便错误以翻译语言显示。 当您的初始化函数分配给该变量时,您的编译器可能会认为该变量需要存在才能使编译成功。

GCC(我假设铿锵声)不会警告未使用的常量。 要注意的一个陷阱是指针需要是const指针,而不仅仅是指向const的指针; 因此,要正确声明一个不会触发任何警告的未使用的字符串常量,您需要:

 const char * const myConst = "myConst"; 

您可以将所有静态变量声明移动到相应的.m文件中。 这应该消除所有那些“未使用的变量”警告。 原因是静态变量仅限于文件级范围。