1.NSInvalidArgumentException 异常
出现这种异常的原因一般是在不可以出现nil数据的时候传入了nil,比如在创建NSDictionary的时候值传入了nil就会出现这种崩溃错误,如果必须传空需要把nil对象转成NSNull才可以确保不出现这种错误,有3种方案可以解决该问题,如下:
方案一:后台在返回数据的时候进行校验,对空值进行处理。但是在项目中有些空值是有特殊的用途,此种方案不可行。
方案二:在转换成NSDictionary的时候,对后台返回的数据进行校验,把空值转换成NSNull对象。方案可行,但是需要对现有代码做大的改动,每次转换的时候都需要进行校验,太麻烦。业务高速发展时期,这样做成本太高。
方案三:有没有一种无须改动现有代码又能解决该问题呢?答案是有的,可以利用Objective-C的runtime来解决该问题。
NSDictionary插入nil对象会造成崩溃,但是插入NSNull对象是不会造成崩溃的,只要利用runtime的Swizzle Method把nil对象给转换成NSNull对象就可以把该问题给解决了。创建一个NSDictionary的类别,利用runtime的Swizzle Method来替换系统的方法。源码实现可以参考Glow团队封装的NSDictionary+NilSafe(Github上可下载到), 现截取其中的部分代码如下:
+ (instancetype)gl_dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(NSUInteger)cnt {
id safeObjects[cnt];
id safeKeys[cnt];
NSUInteger j = 0;
for (NSUInteger i = 0; i < cnt; i++) {
id key = keys[i];
id obj = objects[i];
if (!key) {
continue;
}
if (!obj) {
obj = [NSNull null];
}
safeKeys[j] = key;
safeObjects[j] = obj;
j++;
}
return [self gl_dictionaryWithObjects:safeObjects forKeys:safeKeys count:j];
}
2.data parameter is nil
NSJSONSerialization序列化的时候,传入data为nil,造成的崩溃,这个问题比较好解决,在序列化的时候,统一加入判断,判断data是不是nil即可。
3.unrecognized selector sent to instance 0x15d23910
造成这条崩溃的原因,想必大家都比较熟悉了,就是一个类调用了一个不存在的方法,造成的崩溃。解决这样的问题,可以在写一个方法的时候,判断一下其类的类型,不符合类型的不让其调用
4.SIGSEGV 异常
当去访问没有被开辟的内存或者已经被释放的内存时,就会发生这样的异常。另外,在低内存的时候,也可能会产生这样的异常,一般开发中用到C语言呢的时候比较容易出现这种错误,因为ARC并不会对C语言进行内存管理,所以用C语言创建的对象一定要手动Free
5.Can't add self as subview crash
造成这个崩溃的原因,一种原因是在push或pop一个视图的时候,并且设置了animated:YES,如果此时动画(animated)还没有完成,这个时候,你在去push或pop另外一个视图的时候,就会造成该异常。
解决该异常最简单的方式是把animated设置为NO,但是很不友好,把系统自带的动画效果给去掉了。另外一种友好的方式就是通过runtime来进行实现了,通过安全的方式,确保当有控制器正在进行入栈或出栈时,没有其他入栈或出栈操作
6.NSRangeException 异常
越界异常,一般就是数组越界或者字符串截取越界
7.SIGPIPE 异常
先解释一下什么是SIGPIPE异常,通俗一点的描述是这样的:对一个端已经关闭的socket调用两次write,第二次write将会产生SIGPIPE信号,该信号默认结束进程。
那如何解决该问题呢?对SIGPIPE信号可以进行捕获,也可将其忽略,对于iOS系统来说,只需要把下面这段代码放在.pch文件中即可。
// 仅在 IOS 系统上支持 SO_NOSIGPIPE
#if defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL)
// We do not want SIGPIPE if writing to socket.
const int value = 1;
setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(int));
#endif
8.SIGABRT 异常
这是一个让程序终止的标识,会在断言、app内部、操作系统用终止方法抛出。通常发生在异步执行系统方法的时候。如CoreData、NSUserDefaults等,还有一些其他的系统多线程操作。
注意:这并不一定意味着是系统代码存在bug,代码仅仅是成了无效状态,或者异常状态。