iOS应用Crash是令我们开发者比较头疼的一件事情。比如线上应用的闪退,老板会很慌,你比老板更慌。所以说,有没有一劳永逸的办法来解决呢,看了网易的大白崩溃,感觉又发现了新大陆。附:Demo 不定期更新中….
iOS常见的几种Crash类型
- unrecognized selector crash
- KVO crash
- NSNotification crash
- NSTimer crash
- Container crash(数组越界,插nil等)
- NSString crash (字符串操作的crash)
- UI not on Main Thread Crash (非主线程刷UI(机制待改善))
- Thread 1:EXC_BAD_ACCESS(code=EXC_I386_GPFLT)(野指针)
unrecognized selector crash
首先需要了解方法调用的大概流程
首先,在相应操作的对象中的缓存方法列表中找调用的方法,如果找到,转向相应实现并执行。
如果没找到,在相应操作的对象中的方法列表中找调用的方法,如果找到,转向相应实现执行
如果没找到,去父类指针所指向的对象中执行1,2.
以此类推,如果一直到根类还没找到,转向拦截调用,走消息转发机制。
如果没有重写拦截调用的方法,程序报错。
注:
- 普通方法的优先级: 分类> 子类 > 父类, 优先级高的同名方法覆盖优先级低的
- +load方法的优先级: 父类> 子类> 分类
- +load方法是在main() 函数之前调用,所有的类文件都会加载,包括分类
+load方法不会被覆盖 - 同一主类的不同分类中的普通同名方法调用, 取决于编译的顺序, 后编译的文件中的同名方法会覆盖前面所有的,包括主类. +load方法的顺序也取决于编译顺序, 但是不会覆盖
分类中的方法名和主类方法名一样会报警告, 不会报错
声明和实现可以写在不同的分类中, 依然能找到实现
当第一次用到类的时候, 如果重写了+ initialize方法,会去调用
当调用子类的+ initialize方法时候, 先调用父类的,如果父类有分类, 那么分类的+ initialize会覆盖掉父类的, 和普通方法差不多
父类的+ initialize不一定会调用, 因为有可能父类的分类重写了它
几个关键的方法
1 | + (BOOL)resolveClassMethod:(SEL)sel; |
