[iOS]异常捕捉
UncaughtExceptionHandler.h
#import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @interface UncaughtExceptionHandler : NSObject @end void UncaughtExceptionHandlerStart(void); NS_ASSUME_NONNULL_END
UncaughtExceptionHandler.m
#import "UncaughtExceptionHandler.h"
#import <UIKit/UIKit.h>
#import <libkern/OSAtomic.h>
#import <execinfo.h> NSString * const UncaughtExceptionHandlerSignalExceptionName = @"UncaughtExceptionHandlerSignalExceptionName";
NSString * const UncaughtExceptionHandlerSignalKey = @"UncaughtExceptionHandlerSignalKey";
NSString * const UncaughtExceptionHandlerAddressesKey = @"UncaughtExceptionHandlerAddressesKey"; volatile int32_t UncaughtExceptionCount = ;
const int32_t UncaughtExceptionMaximum = ; const NSInteger UncaughtExceptionHandlerSkipAddressCount = ;
const NSInteger UncaughtExceptionHandlerReportAddressCount = ; @interface UncaughtExceptionHandler ()
{
BOOL dismissed;
}
@end @implementation UncaughtExceptionHandler + (NSArray *)backtrace
{
void *callstack[];
int frames = backtrace(callstack, );
char **strs = backtrace_symbols(callstack, frames); NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames];
int end = UncaughtExceptionHandlerSkipAddressCount + UncaughtExceptionHandlerReportAddressCount; for (int i = UncaughtExceptionHandlerSkipAddressCount;i < end;i++)
{
[backtrace addObject:[NSString stringWithUTF8String:strs[i]]];
}
free(strs); return backtrace;
} - (void)handleException:(NSException *)exception
{
NSString *reason = [exception reason];
NSString *addresses = [[exception userInfo] objectForKey:UncaughtExceptionHandlerAddressesKey];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@""
message:[NSString stringWithFormat:@"reason:%@\n addresses:%@",reason,addresses]
delegate:self
cancelButtonTitle:@"退出"
otherButtonTitles:@"继续", nil];
[alert show]; CFRunLoopRef runLoop = CFRunLoopGetCurrent();
CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop); while (!dismissed)
{
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:UncaughtExceptionHandlerSignalExceptionName])
{
kill(getpid(), [[[exception userInfo] objectForKey:UncaughtExceptionHandlerSignalKey] intValue]);
}else{
[exception raise];
}
} - (void)alertView:(UIAlertView *)anAlertView clickedButtonAtIndex:(NSInteger)anIndex
{
if (anIndex == )
{
dismissed = YES;
}
} @end void HandleException(NSException *exception);
void SignalHandler(int signal); void UncaughtExceptionHandlerStart(void)
{
NSSetUncaughtExceptionHandler(&HandleException);
signal(SIGABRT, SignalHandler);
signal(SIGILL, SignalHandler);
signal(SIGSEGV, SignalHandler);
signal(SIGFPE, SignalHandler);
signal(SIGBUS, SignalHandler);
signal(SIGPIPE, SignalHandler);
} void HandleException(NSException *exception)
{
int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
if (exceptionCount > UncaughtExceptionMaximum)
{
return;
} NSArray *callStack = [UncaughtExceptionHandler backtrace];
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:[exception userInfo]];
[userInfo setObject:callStack forKey:UncaughtExceptionHandlerAddressesKey]; [[[UncaughtExceptionHandler alloc] init] performSelectorOnMainThread:@selector(handleException:)
withObject:[NSException exceptionWithName:[exception name] reason:[exception reason] userInfo:userInfo]
waitUntilDone:YES];
} void SignalHandler(int signal)
{
int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
if (exceptionCount > UncaughtExceptionMaximum)
{
return;
} NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:[NSNumber numberWithInt:signal] forKey:UncaughtExceptionHandlerSignalKey]; NSArray *callStack = [UncaughtExceptionHandler backtrace];
[userInfo setObject:callStack forKey:UncaughtExceptionHandlerAddressesKey]; [[[UncaughtExceptionHandler alloc] init] performSelectorOnMainThread:@selector(handleException:)
withObject:[NSException exceptionWithName:UncaughtExceptionHandlerSignalExceptionName
reason:[NSString stringWithFormat:@"Signal %d was raised.",signal]
userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:signal]
forKey:UncaughtExceptionHandlerSignalKey]]
waitUntilDone:YES];
}
开启异常捕捉
#import "AppDelegate.h"
#import "UncaughtExceptionHandler.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch. UncaughtExceptionHandlerStart(); return YES;
}
异常示例
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
NSArray *array = @[@""];
NSLog(@"%@",array[]);
}
运行效果

[iOS]异常捕捉的更多相关文章
- iOS异常捕获
文章目录 一. 系统Crash 二. 处理signal 下面是一些信号说明 关键点注意 三. 实战 四. Crash Callstack分析 – 进⼀一步分析 五. demo地址 六. 参考文献 前言 ...
- iOS异常采用处理方式
iOS开发过程中我们经常会遇到异常问题 对异常的处理一般采用打印或者直接抛出.这样可以很方便我们调试过程有所参考,而且方便我们查看异常产生的位置信息 NSError(错误信息) 采用NSError的情 ...
- 基础知识《十》java 异常捕捉 ( try catch finally ) 你真的掌握了吗?
本文转载自 java 异常捕捉 ( try catch finally ) 你真的掌握了吗? 前言:java 中的异常处理机制你真的理解了吗?掌握了吗?catch 体里遇到 return 是怎么处理 ...
- Java多线程——<七>多线程的异常捕捉
一.概述 为什么要单独讲多线程的异常捕捉呢?先看个例子: public class ThreadException implements Runnable{ @Override public void ...
- Oracle- 存储过程和异常捕捉
这段时间晚上有时候去打打球,回家看看电视剧,日子一天天过…….学了点ORACLE存储过程基础,作一下备注,以便日后需查阅. 创建无参存储过程 create procedure p_myPro1 is ...
- php错误及异常捕捉
原文:php错误及异常捕捉 在实际开发中,错误及异常捕捉仅仅靠try{}catch()是远远不够的. 所以引用以下几中函数. a) set_error_handler 一般用于捕捉 E_NOTI ...
- android中全局异常捕捉
android中全局异常捕捉 只要写代码就会有bug,但是我们要想办法收集到客户的bug.有第三方bugly或者友盟等可以收集.但是,android原生就提供了有关收集异常的api,所以我们来学习一下 ...
- Spring 全局异常捕捉
Spring全局异常捕捉类 注解@ControllerAdvice package com.sicdt.sicsign.web.bill.controller; import org.springfr ...
- 5.全局异常捕捉【从零开始学Spring Boot】
在一个项目中的异常我们我们都会统一进行处理的,那么如何进行统一进行处理呢? 新建一个类GlobalDefaultExceptionHandler, 在class注解上@ControllerAdvice ...
随机推荐
- button的OnClickListener的三种实现方法
onclick事件的定义方法,分为三种,分别为在xml中进行指定方法:在Actitivy中new出一个OnClickListenner():实现OnClickListener接口三种方式. 代码分别如 ...
- logminer系列文章一(logminer的使用)
转自 http://blog.itpub.net/26613085/viewspace-1064008/ 1.安装logminer以及生成logminer数据字典所需要的包(需使用sys用户) [or ...
- https的网站用了百度分享后网站在浏览器中不安全解决方法
本文出至:新太潮流网络博客 一.先下载百度分享需要的所有东西 下载地址:http://pan.baidu.com/s/1boM7N8V 二.打开百度分享,获取到分享的代码 三.将下载好的百度分享需要的 ...
- 使用 CLI 创建 Azure VM 的自定义映像
自定义映像类似于应用商店映像,不同的是自定义映像的创建者是你自己. 自定义映像可用于启动配置,例如预加载应用程序.应用程序配置和其他 OS 配置. 在本教程中,你将创建自己的 Azure 虚拟机自定义 ...
- Oracle EBS AP更新供应商地址
SELECT pvs.vendor_site_id, pvs.party_site_id, hps.party_site_name, hps.object_version_number, hps.pa ...
- [WinCE | VS2008 | Solution] VS2008 building WinCE projects taking a long time
1. Open C:\Windows\Microsoft.NET\Framework\v3.5\Microsoft.CompactFramework.Common.targets 2. Find pa ...
- 纲举目张:打通MySQL架构和业务的任督二脉
目前,在很多OLTP场景中,MySQL数据库都有着广泛的应用,也有很多不同的使用方式.从数据库的业务需求.架构设计.运营维护.再到扩容迁移,不同的MySQL架构有不同的特点,适应一定的业务场景,或者解 ...
- ORACLE闪回机制分析与研究应用
1.查看数据库归档和闪回状态,及环境准备SQL> archive log list;SQL> select flashback_on from v$database;关闭数据库,启动归档和 ...
- [翻译] DoImagePickerController
DoImagePickerController An image picker controller with single selection and multiple selection. Sup ...
- ZT C语言链表操作(新增单向链表的逆序建立)
这个不好懂,不如看 转贴:C语言链表基本操作http://www.cnblogs.com/jeanschen/p/3542668.html ZT 链表逆序http://www.cnblogs.com/ ...