iOS 崩溃信息拦截防止闪退

//____________________.h_____________________________

#import<Foundation/Foundation.h>

#import <UIKit/UIKit.h>

@interface UncaughtExceptionHandler :NSObject{

    BOOL dismissed;

}


@end

void HandleException(NSException *exception);

void SignalHandler(int signal);



void InstallUncaughtExceptionHandler(void);


//_______________________.m________________________________________


#import "UncaughtExceptionHandler.h"

#include <libkern/OSAtomic.h>

#include <execinfo.h>

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;

}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值