[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 ...
随机推荐
- GitHub已将持续集成服务器Janky开源
GitHub已将Janky开源,这是他们构建在Jenkins之上的持续集成服务器,并在其中增加了聊天自动化工具Hubot. 除了一般的Jenkins功能之外,Janky还通过Hubot对功能进行了补充 ...
- UnicodeEncodeError: 'ascii' codec can't encode characters in position 2-5: ordin al not in range(128)——解决方案备注
在vim中使用ycm插件时,偶尔会出现: “UnicodeEncodeError: 'ascii' codec can't encode characters in position 2-5: ord ...
- 微信小程序接入腾讯云IM即时通讯(会话列表)
会话列表功能概述: 登录 :先用自己的账号登录腾讯云: 获取会话列表 :登录之后再获取会话列表: 更新未读消息数量 :获取会话列表之后更新未读消息数量 WXML代码(自己写的将就看一下) <vi ...
- 直到黎明 Until Dawn 后感
直到黎明 会免游戏.白金神作.近些年的恐怖电影都有游戏化的趋势,韩国的某岩vlog,美国的真心话大冒险,都把观众作为meta代入游戏,几乎模糊了游戏与游戏的边界,直到黎明这部电影,与当年的暴雨和超凡双 ...
- Html 表单标签 Form
Html表单 #转载请留言联系 表单用于搜集不同类型的用户输入,表单由不同类型的标签组成,相关标签及属性用法如下: 1.<form>标签 定义整体的表单区域 action属性 定义表单数据 ...
- mysql常用语句备忘
1.连接本地数据库 mysql -h localhost -u root -p123 2.连接远程数据库 mysql -h 192.168.0.201 -P 3306 -u root -p123 3. ...
- Ad-hoc 查询以及动态SQL的罪恶[译]
本文为翻译文章,原文地址:https://www.simple-talk.com/blogs/2009/08/03/stolen-pages-ad-hoc-queries-and-the-sins-o ...
- SQL Server ->> 调用系统内建扩展存储过程"master.dbo.xp_delete_file"删除过期备份文件
DECLARE @oldDate DATETIME SET @oldDate = GETDATE()-30 EXECUTE MASTER.dbo.xp_delete_file 0, N'D:\back ...
- Redis 入门之基础
1.安装 redis-windows redis服务端下载 redis客户端下载 redis官网 redis中文网 1.1 Window下安装 redis-server.exe redis.windo ...
- html端输入数据,利用qrcode.js生成打印二维码
在前端页面中导入qrcode.js(下载)和jquery.js(下载) index.html <script> function print() { var textbox1 = $('i ...