当前位置: 首页 > news >正文

手机做任务网站北京响应式网站建设公司

手机做任务网站,北京响应式网站建设公司,wordpress 代码块样式,上海设计展2021室内设计文章目录 1.Crash 捕获1.2.NSException1.2.C异常1.3.Mach异常1.4.Unix 信号 2.Crash 防护2.1.方法未实现2.2.KVC 导致 crash2.3.KVO 导致 crash2.4.集合类导致 crash2.5.其他需要注意场景#xff1a; 1.Crash 捕获 根据 Crash 的不同来源#xff0c;分为以下三类#xff1a… 文章目录 1.Crash 捕获1.2.NSException1.2.C异常1.3.Mach异常1.4.Unix 信号 2.Crash 防护2.1.方法未实现2.2.KVC 导致 crash2.3.KVO 导致 crash2.4.集合类导致 crash2.5.其他需要注意场景 1.Crash 捕获 根据 Crash 的不同来源分为以下三类 1.2.NSException 应用层的异常未被捕获的异常导致程序向自身发送了 SIGABRT 信号而崩溃是应用程序自己可控的。对于未被捕获的异常是可以通过 try-catch 或 NSSetUncaughtExceptionHandler() 机制类捕获的。 常见的 Exception NSInvalidArgumentException非法参数异常。加强对参数的检查避免传入非法参数特别是标记为 nonull 的参数。NSRangeException越界异常NSGenericException遍历的同时对原集合进行修改NSInternalInconsistencyException不一致异常。如 NSDictionary 当 NSMutableNSDictionary 使用。NSFileHandleOperationException文件处理异常。常见的是存储空间不足NSMallocException内存异常。如内存不足。 系统定义的所有 Exception 见 NSExceptionName 捕获 NSExpection // 记录之前的Crash回调函数如果有的话 static NSUncaughtExceptionHandler *previousUncaughtExceptionHandler NULL; (void)registerUncaughtExceptionHandler {// 将别人之前注册的Crash回调取出并备份previousUncaughtExceptionHandler NSGetUncaughtExceptionHandler();// 然后再注册自己的NSSetUncaughtExceptionHandler(UncaughtExceptionHandler); }// 崩溃时的回调函数 static void UncaughtExceptionHandler(NSException * exception) {// 异常的堆栈信息NSArray *stackInfo [exception callStackSymbols];// 出现异常的原因NSString *reason [exception reason];// 异常名称NSString *name [exception name];// 异常错误报告NSString *exceptionInfo [NSString stringWithFormat:uncaughtException异常错误报告:\n name:%\n reason:\n %\n callStackSymbols:\n %, name, reason, [stackInfo componentsJoinedByString:\n]];// 保存Crash日志到沙盒cache目录[SKTool cacheCrashLog:exceptionInfo name:CrashLog(UncaughtException)];// 在自己handler处理完后记得把别人的handler注册回去形成规范的SOPif (previousUncaughtExceptionHandler) {previousUncaughtExceptionHandler(exception);}// 杀掉程序这样可以防止同时抛出的SIGABRT被Signal异常捕获kill(getpid(), SIGKILL); }1.2.C异常 系统捕获到 C 异常后会将其转换为 OC 异常抛出此时的调用堆栈是在异常发生时的队长但若转换失败则会调用 __cxa_throw 抛出异常此时的调用队长是处理异常的堆栈导致原始异常调用堆栈丢失。 捕获 C 异常 设置异常处理函数 g_originalTerminateHandler std::set_terminate(CPPExceptionTerminate);调用 set_terminate(CPPExceptionTerminate) 设置新的全局终止处理函数并保持旧的函数。 重写 __cxa_throw void __cxa_throw(void* thrown_exception, std::type_info* tinfo, void (*dest)(void*)) {// 获取调用堆栈并存储// 再调用原始的 __cxa_throw 函数 }异常处理函数 __cxa_throw 往后执行进入 set_terminate 设置的异常梳理函数。判断如果是 OC 异常则什么也不多让 OC 异常机制处理否则获取异常信息。 1.3.Mach异常 内核层的异常。用户态开发者可以通过 Mach API 设置 thread、task、hot 的异常端口来捕获 Mach 异常。 tasks资源所有权单位。每个任务由一个虚拟地址空间、一个端口权限名称控件、一个或多个线程组成。类似于进程threads任务中 CPU 执行的单位ports安全的单工通信通道只能通过发生和接收功能进行访问。 与 Mach 异常相关的 API 有 task_get_exception_ports获取 task 的异常端口task_set_exception_ports设置 task 的异常端口mach_port_allocate创建调用者指定的端口权限类型mach_port_insert_right将指定的端口插入目标 task 注意避免在 Xcode 联调时监听会死锁。 1.4.Unix 信号 又称 BSD 信号如果开发者没有捕获 Mach 异常则会被 host 层的方法 ux_exception() 将异常转换为对应的 Unix 信号并通过方法 threadsignal() 将信号投递到出错线程。可以同 signal(x, SignalHandler) 来捕获 signal。 信号表 SIGHUP挂起SIGINT程序终止信号 interrupt在用户键入 INTR 字符通常是 Ctrl-C是发出用于通知前台进程组终止进程。SIGQUIT程序退出信号 quit由 QUIT 字符来控制通常是Ctrl-程序在收到该信号退出时会生成 core 文件。SIGILL执行非法指令SIGTRAP由断点指令或陷阱指令SIGABRT程序打断信号 abort。SIGBUS非法地址SIGFPE致命的算术运算错误SIGKILL立即结束程序的运行。不能被阻塞、处理和忽略。SIGUSR1用户信号1SIGSEGV无效内存访问SIGUSR2用户信号2SIGPIPE管道破裂。进程间的通信如管道的异常读写。SIGALRMalarm 发出的信号SIGTERM终止信号可被阻塞和处理。通常用来要求程序自己正常退出SIGSTKFLT栈溢出SIGCHLD子进程退出SIGCONT进程继续SIGSTOP进程停止SIGTSTP进程停止SIGTTIN进程停止后台进程从终端读数据时SIGTTOU进程停止后台进程想终端写数据时SIGURGI/O有紧急数据达到当前进程SIGXCPU进程的CPU时间篇到期SIGXFSZ文件大小超出上限SIGVTALRM虚拟时钟超时SIGPROFprofile 时钟超时SIGWINVH窗口大小改变SIGIOI/O相关SIGPWR关机SIGSYS非法的系统调用 Tips: 在终端输入 kill -l 查看所有的 signal 信号。 捕获信号 // 一般需要捕获的信号 static const int g_fatalSignals[] {SIGABRT,SIGBUS,SIGFPE,SIGILL,SIGPIPE,SIGSEGV,SIGSYS,SIGTRAP, }; void installSignalHandler() {stack_t ss;struct sigaction sa;struct timespec req, rem;long ret;// 申请一块内存空间作为可选的信号处理函数栈使用ss.ss_flags 0;ss.ss_size SIGSTKSZ;ss.ss_sp malloc(ss.ss_size);// 使用 sigaltstack 函数通知系统可选的信号处理栈帧的存在及其位置sigaltstack(ss, NULL);// 指定 SA_ONSTACK 标志通知系统这个信号处理函数应该在可选的栈帧上面执行注册的信号处理函数memset(sa, 0, sizeof(sa));sa.sa_handler handleSignalException;sa.sa_flags SA_ONSTACK;sigaction(SIGABRT, sa, NULL); }void XXXHandleSignalException(int signal) {// 打印堆栈NSMutableString *crashInfo [[NSMutableString alloc] init];[crashInfo appendString:[NSString stringWithFormat:signal:%d\n,signal]];[crashInfo appendString:Stack:\n];void* callstack[128];int i, frames backtrace(callstack, 128);char** strs backtrace_symbols(callstack, frames);for (i 0; i frames; i) {[crashInfo appendFormat:%s\n, strs[I]];}NSLog(%, crashInfo);// 移除其他 Crash 监听, 防止死锁NSSetUncaughtExceptionHandler(NULL);signal(SIGHUP, SIG_DFL);signal(SIGINT, SIG_DFL);signal(SIGQUIT, SIG_DFL);signal(SIGABRT, SIG_DFL);signal(SIGILL, SIG_DFL);signal(SIGSEGV, SIG_DFL);signal(SIGFPE, SIG_DFL);signal(SIGBUS, SIG_DFL);signal(SIGPIPE, SIG_DFL); }2.Crash 防护 2.1.方法未实现 找不到方法的实现unrecognized selector sent to instance查找过程详情可见iOS_Objective-C 消息发送消息查找 及 消息转发过程 解决方案 给 NSObject 新增分类实现消息转发的几个方法来规避 Crash - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {if ([self respondsToSelector:aSelector]) { // 已实现不做处理return [self methodSignatureForSelector:aSelector];}return [NSMethodSignature signatureWithObjCTypes:v:]; } - (void)forwardInvocation:(NSInvocation *)anInvocation {NSLog(% cant responds %, NSStringFromClass([self class]), NSStringFromSelector(anInvocation.selector)); }(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {if ([self respondsToSelector:aSelector]) { // 已实现不做处理return [self methodSignatureForSelector:aSelector];}return [NSMethodSignature signatureWithObjCTypes:v:]; }(void)forwardInvocation:(NSInvocation *)anInvocation {NSLog(% cant responds %, NSStringFromClass([self class]), NSStringFromSelector(anInvocation.selector)); }2.2.KVC 导致 crash KVC 的搜索模式详情可见iOS_KVCKey-Value Coding-2访问者搜索模式当最终找不到对应的key时会导致 crash。 常见场景 场景1key 不存在 XXXClass * obj [[XXXClass alloc] init]; [obj setValue:nil forKey:xxx]; // reason: [XXXClass 0x2810bfa80 setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key xxx.id value [obj valueForKey:xxx]; // Thread 1: [MOPerson 0x600000c76c10 valueForUndefinedKey:]: this class is not key value coding-compliant for the key xxx.场景2key 为 nil XXXClass* obj [[XXXClass alloc] init]; [obj setValue:value forKey:nil]; // reason: *** -[XXXClass setValue:forKey:]: attempt to set a value for a nil key// 另外value 为 nil 不会崩溃 [obj setValue:nil forKey:name];解决方案覆写系统会抛出异常的实现 - (id)valueForUndefinedKey:(NSString *)key {NSLog(Error: valueForUndefinedKey: %, key);return nil; } - (void)setValue:(id)value forUndefinedKey:(NSString *)key {NSLog(Error: setValue:% forUndefinedKey: %, value, key); }2.3.KVO 导致 crash 场景 观察者/被观察者 是局部变量未实现 observeValueForKeyPath:ofObject:changecontext:移除未注册的观察者如重复移除 Tips: 重复添加观察者不会crash但会回调多次 解决方案 addObserver 和 removeObserver 必须成对出现使用 Facebook 的 KVOController 实现 2.4.集合类导致 crash 常见场景 越界 NSArray *arr [NSArray array]; id value [arr objectAtIndex:1]; // Thread 1: *** -[__NSArray0 objectAtIndex:]: index 1 beyond bounds for empty array塞入 nil NSMutableArray *arr [NSMutableArray array]; [arr addObject:nil]; // Thread 1: *** -[__NSArrayM insertObject:atIndex:]: object cannot be nilNSMutableDictionary *dict [NSMutableDictionary dictionary]; [dict setObject:nil forKey:xxx]; // Thread 1: *** -[__NSDictionaryM setObject:forKey:]: object cannot be nil (key: xxx)解决方案 使用 runtime 在这些修改方法调用前添加判空处理详情见Demo 2.5.其他需要注意场景 performSelector: 必须先判断 respondsToSelector:调用 delegate 的方法前必须先判断 respondsToSelector:id 类型不能强转必须先判断 isKindOfClass:访问 UIKit 时一定要 dispatch 到 main queue一个实例不能保证线程访问安全时记得要加读写锁dispatch_group_leave 比 dispatch_group_enter 必须成对出现检查属性的修饰方式 (assign/strong/weak/copy)block 调用前必须判空遍历结合类型对象时不要同时对其进行修改耗时操作一定 dispatch 到子线程避免触发 watchDogDebug 模式开启僵尸模式方便即时发现问题。使用 Xcode 的 Address Sanitizer 检测地址访问越界 参考 iOS Crash/崩溃/异常 捕获 Linux 信号列表 浅谈 iOS 中的 Crash 捕获与防护 iOS中常见Crash总结
http://www.ho-use.cn/article/10812732.html

相关文章:

  • 广州建设网站专家做网站录入和查询需求
  • 网站做三方登陆需要注册公司不做网站维护工资多少
  • excel网站做链接性价比高seo排名
  • 高端的家居行业网站开发通辽网站建设招聘
  • 深圳建设网站的公司新乡网站建设方案
  • 内蒙古赤峰市建设局网站wordpress页面样板
  • 石狮网站开发如何看一个网站是谁做的
  • 网站建设平台报价做衣服 网站
  • 网站轮播图上海门户网站建设
  • 银行门户网站开发python代码大全
  • 桂林医院网站建设注册域名和购买域名
  • 自己做网站怎么编代码全网响应式网站
  • 网站建设在开封找谁做wordpress菜单栏不显示不出来
  • 玉林住房和城乡建设局网站官网网站建设邯郸
  • 买域名后 怎么做网站南宁建设网站培训
  • 网站后台管理系统需求网站建设温江
  • 聊城网站案例六安公司做网站
  • 河北省建设工程协会网站比较有趣的网站
  • 个人怎么做电影相关的网站网站建设用模板好吗
  • 呼市做网站基于asp网站开发 论文
  • ui的设计网站百度文章收录提交入口
  • 浙江网站建设与维护书我爱我家二手房房源官网
  • 扬州市广陵区城乡建设局网站wordpress英文切换
  • 搭建个网站需要多少钱m导航网站如何做淘宝客
  • 网站建设推广优化话术wordpress 高德地图
  • 呼和浩特网站建设电话网站建设制作设计营销 中山
  • 西安有哪些网站建设外包公司wordpress怎么插视频
  • 冀州建设局网站如何进行医药网站建设
  • 做购物网站的步骤大竹县国示建设专题网站
  • 钦州房产网站建设番禺网站 建设信科网络