总述
网上不少文章几乎都是你抄我我抄你的,结果要么没一个有用的,要么就太复杂,写文章是给人看的呀,要写得简单通俗啊!于是我干脆自己写一个博客,来简单地说明一下如何通过监听signal来捕获crash。
捕获异常
这个可以通过NSSetUncaughtExceptionHandler并搭配处理异常用的处理函数来使用。
NSSetUncaughtExceptionHandler(&HandleException);
其中HandleException和NSSetUncaughtExceptionHandler都是C语言形式的函数。
捕获signal
这个其实很简单,在崩溃的时候iOS会发出signal,你只需要捕获这个signal并搭配以相应的处理句柄即可做相应的处理。
具体如下:
signal(SIGABRT, handleSignal);
其中signal和handleSignal都是C语言函数,SIGABRT是个宏。
handleSignal就是相应处理的那个句柄了。
完整的组合
因为这些都是C语言函数,所以都是按照C语言的语法来写,不过没关系,你依然可以写在OC的源文件中,只不过把OC的源文件当做一个载体来使用罢了。下面这个是头文件.h代码。
#import <Foundation/Foundation.h>
@interface CrashExceptionHandler : NSObject
@end
void RegisterSignalHandler(void);
实现文件.m代码
#import "CrashExceptionHandler.h"
void HandleException(NSException *exception);
void handleSignal(int signo);
@implementation CrashExceptionHandler
@end
void HandleException(NSException *exception) {
printf("这是在处理异常\n");
[[NSNotificationCenter defaultCenter] postNotificationName:@"hello" object:nil];
}
void handleSignal(int signo) {
printf("这是在处理信号\n");
[[NSNotificationCenter defaultCenter] postNotificationName:@"hello" object:nil];
}
void RegisterSignalHandler(void) {
NSSetUncaughtExceptionHandler(&HandleException);
//注册程序由于abort()函数调用发生的程序中止信号
signal(SIGABRT, handleSignal);
//注册程序由于非法指令产生的程序中止信号
signal(SIGILL, handleSignal);
//注册程序由于无效内存的引用导致的程序中止信号
signal(SIGSEGV, handleSignal);
//注册程序由于浮点数异常导致的程序中止信号
signal(SIGFPE, handleSignal);
//注册程序由于内存地址未对齐导致的程序中止信号
signal(SIGBUS, handleSignal);
//程序通过端口发送消息失败导致的程序中止信号
signal(SIGPIPE, handleSignal);
}
如何使用?
你需要在AppDelegate.m中,像下面这样使用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
RegisterSignalHandler();
return YES;
}
注意
在debug模式下,如果你触发了崩溃,那么应用会直接崩溃到主函数,断点都没用,此时没有任何log信息显示出来,如果你想看log信息的话,你需要在lldb中,拿SIGABRT来说吧,敲入pro hand -p true -s false SIGABRT命令,不然你啥也看不到。
在工程中设置一个断点,以便能够使用调试命令。
1.png运行工程选择第一个选项——SIGABRT,运行到断点的时候在控制台输入"注意"我写的那个命令。
2.png跳过断点继续运行就可以看到结果了。
3.png
源代码
这是用Objective-C编写的,运行于iOS平台的,用XCode跑的,不要搞错了。进入APP是紫色的启动页面,再进去是一个列表,每个单元格都会触发一个崩溃。运行之前现在viewDidLoad里面设个断点,然后输入我在"注意"中写的命令,就可以在崩溃之前看到相应的log输出了。好了,大致的内容就说到这里了,详细地就自己看demo吧,很简单哒,干扰因素忒少。点此下载
多谢捧场
如果您觉得我的文章有价值,那么赏脸打赏一个,鄙人感激不尽。不过,不打赏看看也是好的,如果有不对的地方,还请您多多指正。
网友评论