Objective-C Exception
异常通常包括一下几种NSInvalidArgumentException
非法参数异常(NSInvalidArgumentException)是 Objective - C 代码最常出现的错误,传入非法参数导致异常,其中尤以nil参数为甚。
1. 集合数据的参数传递
- NSDictionary不能添加nil的对象
- 不能插入nil的对象
2.未实现的方法
- .h文件里函数名,却忘了修改.m文件里对应的函数名
- MRC时,大部分情况下是因为对象被提前release了,在你心里不希望他release的情况下,指针还在,对象已经不在 了。
NSRangeException
越界异常(NSRangeException)也是比较常出现的异常
数组最大下标处理错误
NSGenericException
NSGenericException这个异常最容易出现在foreach操作中,在for in循环中如果修改所遍历的数组,无论你是add或remove,都会出错,比如:
执行上面的代码会出现以下的错误:
原因就在这 "for in",它的内部遍历使用了类似 Iterator进行迭代遍历,一旦元素变动,之前的元素全部被失效,所以在foreach的循环当中,最好不要去进行元素的修改动作,若需要修改,循环改为for遍历,由于内部机制不同,不会产生修改后结果失效的问题。
NSFileHandleOperationException
处理文件时的一些异常,最常见的还是存储空间不足的问题,比如应用频繁的保存文档,缓存资料或者处理比较大的数据
Mach Exception
Mach异常是指最底层的内核级异常。
最常见的Mach异常:EXC_BAD_ACCESS (Bad Memory Access)
这种内存访问异常分为访问非法地址(SIGBUS信号)和访问了被回收掉的内存(SIGSEGV信号),实际开发中遇到的错误通常令人莫名其妙,往往需要大量时间来排查,非常头疼。
一些其他的Mach异常:
Unix Signal Exception
从Mach异常最终会转化成Unix信号投递到出错的线程
Crash日志
Crash收集上报的堆栈信息解析
异常信息有三种类型:
1.已标记错误位置的:
test 0x000000010bfddd8c -[ViewController viewDidLoad] + 8588
- 这种信息已经很明确了,不用解析
2.有模块地址的情况:
test 0x00000001018157dc 0x100064000 + 24844252
以上面为例子,从左到右依次是:
二进制库名(test),调用方法的地址(0x00000001018157dc),模块地址(0x100064000)+偏移地址(24844252)
3.无模块地址的情况:
test 0x00000001018157dc test + 24844252
解析堆栈信息:
dSYM符号表获取,xcode->window->organizer->右键你的应用 show finder->右键.xcarchive 显示包内容->dSYMs->test.app.dYSM
然后使用atos命令来符号化某个特定模块加载地址
atos [-arch 架构名] [-o 符号表] [-l 模块地址] [方法地址]
使用终端,进到test.app.dYSM所在目录
1.如果是有模块地址的情况,运行:atos -arch arm64 -o test.app.dSYM/Contents/Resources/DWARF/test -l 0x100064000 0x00000001018157dc
2.如果是无模块地址的情况:
1.先将偏移地址转为16进制:
24844252 = 0x17B17DC
2.然后用方法的地址-偏移地址,得到的就是模块地址
0x00000001018157dc - 0x17B17DC = 0x100064000
3.最后运行:
atos -arch arm64 -o test.app.dSYM/Contents/Resources/DWARF/test -l 0x100064000 0x00000001018157dc