Martin的回答是正确的。然而,我想稍微解释一下,为什么是这样。
您的函数定义:
void myHandler(NSException * exception)
{
}
定义了一个可供外部使用的函数。换句话说,将在目标文件中创建一个符号,以便链接器可以找到它,从而允许其他文件调用 myHandler
。
然而,由于它应该是可供外部使用的,因此其他文件需要知道该函数的外观。这就是原型的作用。警告基本上是在说...
嘿,你已经声明了这个函数可供其他代码外部访问,但我没有看到其他代码可以使用以了解该函数信息的原型。
所以,你会收到一个警告。这是一个很好的警告。它会帮助你记得为想要导出的函数声明原型。
现在,正如您发现的那样,您可以声明原型,然后警告消失了。但是,在实现文件中仅声明原型对您来说也应该是另一个警告。个人警告应该是:
您真的希望这个函数具有外部可见性,还是仅在这个编译单元中调用?如果该函数不会具有外部可见性,则无需在符号表中导出该函数,并且其他模块可以包括以了解该函数的原型。
在这种情况下,您可以像Martin的响应中那样声明函数为 static
:
static void myHandler(NSException * exception)
{
}
在这种情况下,
static
告诉编译器以下内容:
嘿,编译器,在此函数中创建代码,并允许此编译单元中的任何代码看到该函数,但不要使其对外可见。我不希望其他模块调用该函数。
在这种情况下,即使其他代码声明了原型,它们也无法看到您的函数,因为它是“私有”的,仅限于定义它的文件中。
由于它仅在本地文件中使用,因此不需要原型,因此也没有必要警告您没有原型。
现在只是一条注释...... 您不需要将C函数放入代码的@interface和@implementation部分中,因为那样不起任何作用。那些C函数无论是在ObjC部分内还是外都具有完全相同的可见性和访问权限。
最后,如果您愿意,可以在Xcode构建设置中禁用此警告(但既然您理解了警告的上下文,我建议将其打开)。
myHandler
已在AppDelegate
中注册,但未捕获的异常可能发生在任何类中,因此我不确定是否适合使用static
… - Ryanstatic
,因为你将myHandler
的地址传递给了NSSetUncaughtExceptionHandler
。 可见性只对链接器很重要。 如果任何模块都有myHandler
的地址,则可以独立于可见性调用此函数。- 将局部静态函数的地址传递给其他函数是一种常见模式,例如回调函数等。 - Martin R