您的位置:首页 > 移动开发 > IOS开发

iOS 崩溃信息拦截防止闪退

2016-06-07 17:37 465 查看
//____________________.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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: