Register UncaughtExceptionHandler in Objective-C using NSSetUncaughtExceptionHandler

My code for registering an uncaught exception handler using UncaughtExceptionHandler as follows: what do you think is some potential problem?

 @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 a class extension to declare a prototype in order to get rid of the warning No previous prototype for a function.

+5
c ios objective-c iphone xcode
Aug 31 2018-12-12T00:
source share
3 answers

Martin's answer is correct. However, I thought I thought a little to explain why this is so.

Definition of your function:

 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 .

However, since it must be externally visible, other files will need to know how this function looks. That the prototype comes into play. The warning basically says ...

Hey, you declared this function externally visible to other code, but I don’t see a prototype that can use other code for about the function.

So you will get a warning. This is a good warning. This helps you forget to declare prototypes for the functions you want to export.

Now, as you have discovered, you can declare a prototype and the warning will disappear. However, declaring a prototype only in the implementation file should be another warning for you. This personal warning should be:

Do you really want this function to have external visibility, or is it called only in this compilation unit? If the function does not have external visibility, then there is no need to export it to the symbol table, and there is no need for a prototype, which other modules can include so that they know about the function.

In this case, you can declare a static function as in Martin's answer:

 static void myHandler(NSException * exception) { // ... } 

In this context, static tells the compiler something like:

Hi compiler, create code for this function and allow any code in this compilation block to see the function but not give it external appearance. I do not want the function to be called by other modules.

In this case, even if another code declared a prototype, they will not see your function, because it is "private" to the file in which it is defined.

Since it is used only in the local file, there is no need for a prototype, so there is no need to warn you that you do not have it.

Now, as a note ... You do not need to introduce C functions in the @interface and @implementation sections of your code, as this does nothing. These C functions are compiled with the same visibility and access, regardless of whether they are in ObjC sections or not.

Finally, if you want, you can turn off this warning in the Xcode build settings (but now that you understand the context of the warning, I suggest leaving it).

+10
Aug 31 2018-12-12T00:
source share

You will not receive a warning about a missing prototype if you declare the function as static :

 static void myHandler(NSException * exception) { // ... } 
+3
Aug 31 '12 at 12:44
source share

Yes, that is the right way. I'm just wondering why you get the warning, because I have the same thing without declaring it in an empty category, and I don't get the warning ... In addition, you can also set signal handlers for catch SIGABRT , SIGILL and 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); ... } 
0
Aug 31 '12 at 12:40
source share



All Articles