遍历集合先Copy
如果你正在遍历的集合是mutable的,在你遍历的同时,可能另外一个线程对这个集合做了修改,一个Crash将出现.
|
|
如何避免呢?
拿到NSArray/NSMutableArray、NSDictionary/NSMutableDictionary都copy一下。
集合操作要预判
提前做好判断,保证key/value不为nil,数组不会越界。
|
|
NSKeyedArchiver别常用
在iOS8上会抛exception,非要用加上@try{}@catch{}
KVO成对出现
有add必要有remove,否则极有可能Crash,可以使用FaceBook的FBKVOController
tableView的delegate要置空
viewController的dealloc把tableView的delegate置空
iOS8及以前,delegate属性不是weak,不会自动设为nil。否则做异步网络请求,退出页面就容易出现野指针。
不要在Category覆盖系统方法
不要坑别人
Api需要特定线程,记得加断言
如果一个api需要在特定线程执行,记得加上断言判断,否则调用方容易在不合适的线程调用,导致Crash
多线程环境下懒加载变量要加锁
|
|
NSNotificationCenter要防止Self为空
NSNotificationCenter在iOS 8及更老系统上存在多线程bug,selector执行到一半时可能会因为self销毁而触发crash.
|
|
使用dispatch_sync要小心
容易死锁。下面将一个Block同步到主线程的队列里。因为你用同步,必须先让你执行,但你放到主线程队列里,却要等待主线程原来的任务执行完。
cancelPreviousPerformRequestsWithTarget要防御
对receiver使用cancelPreviousPerformRequestsWithTarget,会导致receiver引用计数减1。如果调用前receiver的引用计数就是1,调用完receiver就会被释放。
|
|
在dealloc中,不要将self作为参数传递
如果self在此时被retain住,到下个runloop周期再次释放,则会造成多次释放crash。
|
|
因为当前已经在self所指向对象的销毁阶段,如果在doSome:中将self放到了autorelease pool中,那么self会被retain住,计划下个runloop周期再进行销毁;但是dealloc运行结束后,self对象的内存空间就直接被回收了,self变成了野指针
当到了下个runloop周期,self指向的对象实际上已经被销毁,会因为非法访问造成crash问题
使用锁要避免出现特殊逻辑锁没有被回收
如果某个方法里锁未被回收,下次调用该方法会造成线程死锁
可能提前出现return,要在return前回收
|
|
可能出现异常,要在finally回收
|
|