xcode 使用 NSSetUncaughtExceptionHandler 在 Objective C 中注册 UncaughtExceptionHandler
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12215012/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Register UncaughtExceptionHandler in Objective C using NSSetUncaughtExceptionHandler
提问by Ryan
My code for registering uncaught exception handler using UncaughtExceptionHandler
is as following, do you think there will be any potential issue?
我使用注册未捕获的异常处理程序的代码UncaughtExceptionHandler
如下,您认为会有任何潜在问题吗?
@interface AppDelegate ()
void myHandler(NSException * exception);
@end
@implementation AppDelegate
void myHandler(NSException * exception)
{
// ...
}
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSSetUncaughtExceptionHandler(&myHandler);
..
Is it possible to have a more concise way to write it?
有没有更简洁的写法?
I need to use the class extension to declare prototype in order to get rid of the warning of No previous prototype for function ..
我需要使用类扩展来声明原型,以摆脱No previous prototype for function ..
回答by Jody Hagins
Martin's answer is correct. However, I thought I'd elaborate just a bit, to explain why it is so.
马丁的回答是正确的。但是,我想我会详细说明一下,以解释为什么会这样。
Your function definition:
您的函数定义:
void myHandler(NSException * exception)
{
// ...
}
defines a function that will be externally visible. In other (generalized, non-technical) words, a symbol will be created in the object file so that the linker can find it, which allows other files to call myHandler
.
定义一个外部可见的函数。换句话说,将在目标文件中创建一个符号,以便链接器可以找到它,从而允许其他文件调用myHandler
.
However, because it is supposed to be externally visible, other files are going to have to know what that function looks like. That's where the prototype comes into play. The warning is basically saying...
但是,因为它应该是外部可见的,所以其他文件将不得不知道该函数的外观。这就是原型发挥作用的地方。警告基本上是说......
Hey, you have declared this function to be externally visible to other code, but I don't see a prototype that other code can use to know about the function.
嘿,您已声明此函数对其他代码在外部可见,但我没有看到其他代码可以用来了解该函数的原型。
So, you get a warning. It's a good warning to have on. It helps you remember to declare prototypes for functions that you want to export.
所以,你会收到警告。这是一个很好的警告。它可以帮助您记住为要导出的函数声明原型。
Now, as you discovered, you can declare a prototype, and the warning goes away. However, declaring the prototype just in the implementation file should be another warning to you. That personal warning should be:
现在,正如您所发现的,您可以声明一个原型,警告就会消失。但是,仅在实现文件中声明原型应该是对您的另一个警告。个人警告应该是:
Do you really want this function to have external visibility, or is it just called in this compilation unit? If the function is not going to have external visibility, then there is no need to export it in the symbol table, and there is no need for a prototype that other modules can include so they know about the function.
你真的希望这个函数具有外部可见性,还是只是在这个编译单元中调用?如果函数不具有外部可见性,则不需要将其导出到符号表中,也不需要其他模块可以包含的原型,以便他们了解该函数。
In that case, you can declare the function static
as in Martin's response:
在这种情况下,您可以static
按照 Martin 的回复声明该函数:
static void myHandler(NSException * exception)
{
// ...
}
In this context, static
tells the compiler something like:
在这种情况下,static
告诉编译器类似:
Hey, compiler, create code for this function, and allow any code in this compilation unit to see the function, but do not give it external visibility. I don't want the function to be called by other modules.
嘿,编译器,为这个函数创建代码,并允许这个编译单元中的任何代码看到这个函数,但不要给它外部可见性。我不希望该函数被其他模块调用。
In this case, even if other code declared the prototype, they would not see your function because it is "private" to the file in which it is defined.
在这种情况下,即使其他代码声明了原型,他们也不会看到您的函数,因为它对于定义它的文件是“私有的”。
Since it is being used only in the local file, there is no need for a prototype, so there is no need to warn you that you don't have one.
由于它仅在本地文件中使用,因此不需要原型,因此无需警告您没有原型。
Now, just as a note... You don't need to put C functions in the @interface and @implementation sections of your code, as that does nothing. Those C functions are compiled with the exact same visibility and access whether they are inside the ObjC sections or not.
现在,请注意...您不需要将 C 函数放在代码的 @interface 和 @implementation 部分中,因为这什么都不做。这些 C 函数编译时具有完全相同的可见性和访问权限,无论它们是否在 ObjC 部分中。
Finally, if you want, you can disable this warning in the Xcode build settings (but now that you understand the context of the warning, I suggest leaving it on).
最后,如果您愿意,您可以在 Xcode 构建设置中禁用此警告(但现在您了解警告的上下文,我建议将其保留)。
回答by Martin R
You do not get a warning about a missing prototype if you declare the function as static
:
如果将函数声明为static
:
static void myHandler(NSException * exception)
{
// ...
}
回答by graver
Yes, this is the correct way. I am just wondering why do you get the warning as I have the same thing without declaring it in an empty category and I don't get a warning... In addition you can also set signal handlers to catch SIGABRT
, SIGILL
and SIGBUS
signals:
是的,这是正确的方法。我只是想知道为什么你得到警告,因为我有同样的事情,没有一个空的类别宣布它,我没有得到一个警告。除此之外,你还可以设置信号处理程序捕获SIGABRT
,SIGILL
并且SIGBUS
信号:
void signalHandler(int sig) {
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
struct sigaction newSignalAction;
memset(&newSignalAction, 0, sizeof(newSignalAction));
newSignalAction.sa_handler = &signalHandler;
sigaction(SIGABRT, &newSignalAction, NULL);
sigaction(SIGILL, &newSignalAction, NULL);
sigaction(SIGBUS, &newSignalAction, NULL);
...
}