美文网首页iOS Developer
iOS | 避免NSNotification引起的Crash

iOS | 避免NSNotification引起的Crash

作者: Mrshang110 | 来源:发表于2017-04-18 20:44 被阅读273次

    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

        本文链接:https://www.haomeiwen.com/subject/hmdqzttx.html