iOS | 避免NSNotification引起的Crash

2017.8.4更新

如果只需兼容iOS9.0和macOS10.11及其以后版本,不需要主动取消通知注册.如果有低版本支持的需求,请继续往下阅读.


NSNotification在什么情境下会引起Crash呢?一个稍有经验的开发者很快就能想到原因:一个对象注册了通知,在销毁时忘记取消注册.

在开发中,通知算是比较常用的.如何更好地使用通知,写出更健壮的代码,值得我们思考一下.

(取消)注册时机

在viewDidLoad进行注册通知的开发者应该不是少数.在这里注册,似乎不会有什么问题,毕竟view unload出现的可能性不是很大.作为开发者,我们要知道这种情况的存在.view是可以unload和reload的.

一旦view unload了,viewDidLoad就调用不止一次.一个对象多次注册通知,自然也会多次接收到通知.

在viewWill/DidAppear里注册,也会导致注册多次,除非在viewWill/DidDisappear取消注册.在viewWill/DidDisappear取消注册,会导致一个问题,页面进入下一级页面时就无法收到通知.

一般情况下,最合适的时机是在init方法注册,dealloc方法取消注册.

优雅取消注册的方式

应该有人像下面这样写取消注册的代码

- (void)dealloc
{
  [[NSNotificationCenter defaultCenter] removeObserver:self name:kSomeNotificationName object:someObject];
  ...
}

这样写没问题.但是这样写,可维护性并不高.如果某天新加一个kSomeOtherNotificationName通知,忘了取消就会导致Crash.

下面这种写法,既简洁又避免了忘记取消新的通知注册问题.

- (void)dealloc
{
  [[NSNotificationCenter defaultCenter] removeObserver:self];
}

主线程调用

我想不会有人在其他线程去取消注册,如果你真这么做,我也无话可说.在其他线程发送通知,会引起很多隐藏的bug.切记,发通知时一定要在主线程.

你可能感兴趣的:(iOS | 避免NSNotification引起的Crash)