You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止iOS App崩溃时退出并显示指定报错提示?

iOS Crash Interception: Show Custom Message & Prevent App Exit

Hey there! Let's tackle your two key questions head-on—yes, you can prevent your iOS app from exiting on most crashes, and I'll walk you through how to display that custom error message while keeping the app running.

First: Can We Block iOS App Crash Exit?

Short answer: For most common crash types (unhandled Objective-C exceptions, common signals like SIGSEGV/SIGABRT), yes. But there are important caveats to keep in mind:

  • System-level termination signals like SIGKILL can't be intercepted (this is sent by iOS when your app uses too much memory or violates core system rules).
  • After intercepting a crash, your app's internal state might be unstable (e.g., leaked memory, corrupted data). This is a user experience band-aid, not a permanent fix—you should always log crash details to debug and resolve the root cause later.
  • Apple's App Store review may flag this approach, as hiding crashes can mask serious app issues. Use this only as a temporary measure to improve user experience while you work on fixes.

Step-by-Step Implementation

We'll need to handle two categories of crashes: Objective-C uncaught exceptions and C-level signals. Here's how to set it up:

1. Handle Uncaught Objective-C Exceptions

Add a custom exception handler to catch unhandled exceptions, show your error message, and keep the app running.

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>

void UncaughtExceptionHandler(NSException *exception) {
    // Optional: Log crash details for debugging
    NSString *crashLog = [NSString stringWithFormat:@"Exception Type: %@\nStack Trace:\n%@", 
                          exception.name, exception.callStackSymbols];
    NSLog(@"Uncaught Exception:\n%@", crashLog);
    
    // Show the custom error alert on the main thread
    dispatch_async(dispatch_get_main_queue(), ^{
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Oops!" 
                                                                       message:@"sorry some thing went wrong" 
                                                                preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" 
                                                           style:UIAlertActionStyleDefault 
                                                         handler:nil];
        [alert addAction:okAction];
        
        // Get the topmost view controller to present the alert
        UIViewController *topVC = [UIApplication sharedApplication].keyWindow.rootViewController;
        while (topVC.presentedViewController) {
            topVC = topVC.presentedViewController;
        }
        [topVC presentViewController:alert animated:YES completion:nil];
        
        // Keep the app running by starting a new runloop (the original one was terminated by the exception)
        CFRunLoopRun();
    });
}

2. Handle C-Level Signals

Many crashes (like memory access errors) trigger C signals. We'll register signal handlers to catch these, then switch to the main thread to show the alert (signal handlers can't call UIKit directly).

#include <signal.h>
#include <execinfo.h>

static BOOL hasCrashed = NO; // Prevent duplicate handling of the same crash

void SignalHandler(int signal) {
    if (hasCrashed) return;
    hasCrashed = YES;
    
    // Optional: Log signal crash details
    void* callstack[128];
    int frameCount = backtrace(callstack, 128);
    char** stackSymbols = backtrace_symbols(callstack, frameCount);
    
    NSMutableString *crashLog = [NSMutableString string];
    for (int i = 0; i < frameCount; i++) {
        [crashLog appendFormat:@"%s\n", stackSymbols[i]];
    }
    free(stackSymbols);
    NSLog(@"Signal %d Crash:\n%@", signal, crashLog);
    
    // Show the alert on main thread
    dispatch_async(dispatch_get_main_queue(), ^{
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Oops!" 
                                                                       message:@"sorry some thing went wrong" 
                                                                preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" 
                                                           style:UIAlertActionStyleDefault 
                                                         handler:nil];
        [alert addAction:okAction];
        
        UIViewController *topVC = [UIApplication sharedApplication].keyWindow.rootViewController;
        while (topVC.presentedViewController) {
            topVC = topVC.presentedViewController;
        }
        [topVC presentViewController:alert animated:YES completion:nil];
        
        // Keep the app alive
        CFRunLoopRun();
    });
}

3. Register Handlers in AppDelegate

Add these lines to your application:didFinishLaunchingWithOptions: method to activate the handlers:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Register Objective-C exception handler
    NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
    
    // Register signal handlers for common crash signals
    signal(SIGABRT, SignalHandler);
    signal(SIGSEGV, SignalHandler);
    signal(SIGBUS, SignalHandler);
    signal(SIGILL, SignalHandler);
    signal(SIGFPE, SignalHandler);
    
    return YES;
}

Critical Notes to Remember

  • Fix the root cause first: This interception is for user experience, not to ignore bugs. Make sure you log crash details (to a local file or remote service) so you can debug and fix the underlying issues.
  • App stability: After a crash, the app might be in an inconsistent state. Consider adding an action to the alert that lets users restart the app (e.g., call exit(0) after user confirmation to trigger a clean relaunch).
  • Swift limitations: Swift runtime errors (like force-unwrapping nil) won't trigger the Objective-C exception handler. For Swift apps, you'll need additional error handling or use a crash reporting library that supports Swift-specific crashes.

内容的提问来源于stack exchange,提问作者user3051331

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:53:02