第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

IOS應(yīng)用崩潰復(fù)活

標(biāo)簽:
iOS

IOS应用崩溃一直是一个很苦恼的问题,而崩溃的同时又未获取bug原因,更令人苦恼。
好在苹果自带的crash检测api,以及runloop可以让应用复活一次,不过第二次依旧会崩溃,但是还是一个很实用的小技巧。
以下是IOS崩溃复活的类和使用方法

#import "CrashHandler.h"

//Appdelagte中注册crash记录上报
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  // Override point for customization after application launch.
  [CrashHandler sharedInstance];
  return YES;
}

//.h文件
#import <Foundation/Foundation.h>

@interface CrashHandler : NSObject
{
  BOOL ignore;
}

+ (instancetype)sharedInstance;

@end

//.m文件
#import "CrashHandler.h"
#import <UIKit/UIKit.h>
#include <libkern/OSAtomic.h>
#include <execinfo.h>

NSString * const kSignalExceptionName = @"kSignalExceptionName";
NSString * const kSignalKey = @"kSignalKey";
NSString * const kCaughtExceptionStackInfoKey = @"kCaughtExceptionStackInfoKey";

void HandleException(NSException *exception);
void SignalHandler(int signal);

@implementation CrashHandler

static CrashHandler *instance = nil;

+ (instancetype)sharedInstance
{
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    instance = [[[self class] alloc] init];
  });
  return instance;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    instance = [super allocWithZone:zone];
  });
  return instance;
}

- (instancetype)init
{
  self = [super init];
  if (self) {
    [self setCatchExceptionHandler];
  }
  return self;
}

- (void)setCatchExceptionHandler
{
  // 1.捕获一些异常导致的崩溃
  NSSetUncaughtExceptionHandler(&HandleException);
   
  // 2.捕获非异常情况,通过signal传递出来的崩溃
  signal(SIGABRT, SignalHandler);
  signal(SIGILL, SignalHandler);
  signal(SIGSEGV, SignalHandler);
  signal(SIGFPE, SignalHandler);
  signal(SIGBUS, SignalHandler);
  signal(SIGPIPE, SignalHandler);
}

+ (NSArray *)backtrace
{
  void* callstack[128];
  int frames = backtrace(callstack, 128);
  char **strs = backtrace_symbols(callstack, frames);
   
  NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames];
  for (int i = 0; i < frames; i++) {
    [backtrace addObject:[NSString stringWithUTF8String:strs[i]]];
  }
  free(strs);
   
  return backtrace;
}

- (void)alertView:(UIAlertView *)anAlertView clickedButtonAtIndex:(NSInteger)anIndex
{
  if (anIndex == 0) {
    ignore = YES;
  } else if (anIndex == 1) {
    NSLog(@"起死回生");
  }
}

- (void)handleException:(NSException *)exception
{
  NSString *message = [NSString stringWithFormat:@"崩溃原因如下:\n%@\n%@",
             [exception reason],
             [[exception userInfo] objectForKey:kCaughtExceptionStackInfoKey]];
  NSLog(@"%@",message);
   
  UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"程序崩溃了"
                          message:@"如果你能让程序起死回生,那你的决定是?"
                          delegate:self
                     cancelButtonTitle:@"崩就蹦吧"
                     otherButtonTitles:@"起死回生", nil];
  [alert show];
   
  CFRunLoopRef runLoop = CFRunLoopGetCurrent();
  CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);
   
  while (!ignore) {
    for (NSString *mode in (__bridge NSArray *)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:kSignalExceptionName]) {
    kill(getpid(), [[[exception userInfo] objectForKey:kSignalKey] intValue]);
  } else {
    [exception raise];
  }
}

@end

void HandleException(NSException *exception)
{
  // 获取异常的堆栈信息
  NSArray *callStack = [exception callStackSymbols];
  NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
  [userInfo setObject:callStack forKey:kCaughtExceptionStackInfoKey];
   
  CrashHandler *crashObject = [CrashHandler sharedInstance];
  NSException *customException = [NSException exceptionWithName:[exception name] reason:[exception reason] userInfo:userInfo];
  [crashObject performSelectorOnMainThread:@selector(handleException:) withObject:customException waitUntilDone:YES];
}

void SignalHandler(int signal)
{
  // 这种情况的崩溃信息,就另某他法来捕获吧
  NSArray *callStack = [CrashHandler backtrace];
  NSLog(@"信号捕获崩溃,堆栈信息:%@",callStack);
   
  CrashHandler *crashObject = [CrashHandler sharedInstance];
  NSException *customException = [NSException exceptionWithName:kSignalExceptionName
                              reason:[NSString stringWithFormat:NSLocalizedString(@"Signal %d was raised.", nil),signal]
                             userInfo:@{kSignalKey:[NSNumber numberWithInt:signal]}];
   
  [crashObject performSelectorOnMainThread:@selector(handleException:) withObject:customException waitUntilDone:YES];
}

點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺(jué)得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評(píng)論
  • 收藏
  • 共同學(xué)習(xí),寫下你的評(píng)論
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說(shuō)多少就多少
贊賞金額會(huì)直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消