iOS 崩溃信息拦截防止闪退

//____________________.h_____________________________

#import

#import

@interface UncaughtExceptionHandler :NSObject{

    BOOL dismissed;

}


@end

void HandleException(NSException *exception);

void SignalHandler(int signal);



void InstallUncaughtExceptionHandler(void);


//_______________________.m________________________________________


#import "UncaughtExceptionHandler.h"

#include

#include

NSString *const UncaughtExceptionHandlerSignalExceptionName =@"UncaughtExceptionHandlerSignalExceptionName";

NSString *const UncaughtExceptionHandlerSignalKey =@"UncaughtExceptionHandlerSignalKey";

NSString *const UncaughtExceptionHandlerAddressesKey =@"UncaughtExceptionHandlerAddressesKey";


volatileint32_t UncaughtExceptionCount =0;

constint32_t UncaughtExceptionMaximum =10;


constNSInteger UncaughtExceptionHandlerSkipAddressCount =4;

constNSInteger UncaughtExceptionHandlerReportAddressCount =5;

@implementation UncaughtExceptionHandler

+ (NSArray *)backtrace {

    void* callstack[128];

    int frames =backtrace(callstack, 128);

    char **strs =backtrace_symbols(callstack, frames);

    int i;

    NSMutableArray *backtrace = [NSMutableArrayarrayWithCapacity:frames];

    for (i = UncaughtExceptionHandlerSkipAddressCount ; i <UncaughtExceptionHandlerSkipAddressCount +UncaughtExceptionHandlerReportAddressCount; i++){

        [backtraceaddObject:[NSStringstringWithUTF8String:strs[i]]];

    }

    free(strs);

    return backtrace;

}


- (void)alertView:(UIAlertView *)anAlertView clickedButtonAtIndex:(NSInteger)anIndex {

    if (anIndex ==0){

        dismissed =YES;

    }elseif (anIndex==1) {

        NSLog(@"ssssssss");

    }

}


- (void)validateAndSaveCriticalApplicationData {

    

}


- (void)handleException:(NSException *)exception {

    [selfvalidateAndSaveCriticalApplicationData];

    NSString *message = [NSStringstringWithFormat:NSLocalizedString(@"如果点击继续,程序有可能会出现其他的问题,建议您还是点击退出按钮并重新打开\n\n"@"异常原因如下:\n%@\n%@",nil),[exceptionreason],[[exceptionuserInfo] objectForKey:UncaughtExceptionHandlerAddressesKey]];

    UIAlertView *alert =[[UIAlertViewalloc]initWithTitle:NSLocalizedString(@"抱歉,程序出现了异常",nil)

                                                 message:message

                                                delegate:self

                                       cancelButtonTitle:NSLocalizedString(@"退出",nil)

                                       otherButtonTitles:NSLocalizedString(@"继续",nil), nil];


    [alert show];

    CFRunLoopRef runLoop = CFRunLoopGetCurrent();

    CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);

    

    while (!dismissed) {

        for (NSString *modein (__bridgeNSArray *)allModes) {

           CFRunLoopRunInMode((CFStringRef)mode,0.001, false);

        }

    }

    

    CFRelease(allModes);

    NSSetUncaughtExceptionHandler(NULL);

    signal(SIGABRT,SIG_DFL);

    signal(SIGILL,SIG_DFL);

    signal(SIGSEGV,SIG_DFL);

    signal(SIGFPE,SIG_DFL);

    signal(SIGBUS,SIG_DFL);

    signal(SIGPIPE,SIG_DFL);

    

    if ([[exception name] isEqual:UncaughtExceptionHandlerSignalExceptionName]) {

        kill(getpid(), [[[exceptionuserInfo] objectForKey:UncaughtExceptionHandlerSignalKey]intValue]);

    }else{

        [exception raise];

    }

}


@end


void HandleException(NSException *exception) {

    int32_t exceptionCount =OSAtomicIncrement32(&UncaughtExceptionCount);

    if (exceptionCount >UncaughtExceptionMaximum) {

        return;

    }

    

    NSArray *callStack = [UncaughtExceptionHandlerbacktrace];

    NSMutableDictionary *userInfo =[NSMutableDictionarydictionaryWithDictionary:[exceptionuserInfo]];[userInfo setObject:callStack forKey:UncaughtExceptionHandlerAddressesKey];

    

    [[[UncaughtExceptionHandleralloc] init]performSelectorOnMainThread:@selector(handleException:)withObject:

     [NSExceptionexceptionWithName:[exceptionname] reason:[exceptionreason] userInfo:userInfo]waitUntilDone:YES];

}


void SignalHandler(int signal) {

    int32_t exceptionCount =OSAtomicIncrement32(&UncaughtExceptionCount);

    if (exceptionCount >UncaughtExceptionMaximum) {

        return;

    }

    

    NSMutableDictionary *userInfo =[NSMutableDictionarydictionaryWithObject:[NSNumbernumberWithInt:signal] forKey:UncaughtExceptionHandlerSignalKey];

    

    NSArray *callStack = [UncaughtExceptionHandlerbacktrace];[userInfo setObject:callStackforKey:UncaughtExceptionHandlerAddressesKey];

    

    [[[UncaughtExceptionHandleralloc] init]performSelectorOnMainThread:@selector(handleException:)withObject:[NSExceptionexceptionWithName:UncaughtExceptionHandlerSignalExceptionNamereason:[NSStringstringWithFormat:NSLocalizedString(@"Signal %d was raised.",nil),signal]userInfo:

      [NSDictionarydictionaryWithObject:[NSNumbernumberWithInt:signal]forKey:UncaughtExceptionHandlerSignalKey]]waitUntilDone:YES];

}


void InstallUncaughtExceptionHandler(void) {

    NSSetUncaughtExceptionHandler(&HandleException);

    signal(SIGABRT,SignalHandler);

    signal(SIGILL,SignalHandler);

    signal(SIGSEGV,SignalHandler);

    signal(SIGFPE,SignalHandler);

    signal(SIGBUS,SignalHandler);

    signal(SIGPIPE,SignalHandler);

}


//_________________调用_________________



- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

InstallUncaughtExceptionHandler();

    return YES;

}




你可能感兴趣的:(UIApplication,App启动)