美文网首页
Swift之正确使用通知

Swift之正确使用通知

作者: 小小土豆dev | 来源:发表于2017-11-14 13:29 被阅读0次

    本文主要介绍,如何在项目中正确的使用通知,在使用之前,先了解几个概念:

    概念一:NotificationCenter(通知中心)

    通知中心实际上是iOS程序内部之间的一种消息广播机制,主要为了解决应用程序内部不同对象之间解耦而设计。它是基于观察者模式设计的,不能跨应用程序进程通信,当通知中心接收到消息之后会根据内部的消息转发表,将消息发送给订阅者。

    通知是同步的,接收通知的对象会在发送通知对象的线程中执行方法,当所有接收对象执行完消息后,发送通知对象才会执行接下来的代码。

    每一个iOS程序都有一个唯一的通知中心,它是系统创建好的一个单例类,不需要我们自己去创建。

    1.获取通知中心

    class var default: NotificationCenter{ get }

    2.在通知中心注册一个通知

    func addObserver(_ observer: Any, selector aSelector: Selector, name aName: NSNotification.Name?, object anObject: Any?)

    概念二:Notification(通知)

    Notification就是我们发送的消息对象,有以下三个常用的属性:

    1.通知的名称,用来标示一个通知,一般为字符串

    public var name:Notification.Name

    2.任意想要携带的对象,通常为发送者自己

    public var object:Any? 

    3.附加信息

    public var userInfo: [AnyHashable: Any]?

    概念三:移除通知

    在通知中心注册通知后,当注册对象销毁时如果不在通知中心中移除通知,当收到通知时,会造成向野指针对象发送消息,会crash。

    1.移除所有通知

    func removeObserver(_observer:Any)

    2.根据通知名称,移除通知

    func removeObserver(_observer:Any, name aName:NSNotification.Name?, object anObject:Any?)


    下面介绍项目中如何正确的使用通知

    方式一:异步发送通知

    上面说过,通知是同步的,它会等到所有接受者执行完代码后,才会执行接下来的代码,如果在当前线程直接发送通知,就会阻塞当前线程,所以将发送通知放在全局并发队列中:

    1.发送通知

    DispatchQueue.global().async{

        NotificationCenter.default.post(name:NSNotification.Name(rawValue: "name"),

                                                        object:nil,

                                                     userInfo:nil)

    }

    2.注册通知

    NotificationCenter.default.addObserver(self,

                            selector:#selector(login(_:)),

                              name:NSNotification.Name(rawValue:"name"),

                             object:nil

    )

    3.收到通知时,执行的方法

    func login(_notification:Notification) {

        DispatchQueue.main.async{

          // 如果更新UI,需要在主线程中

        }

    }

    4.移除通知

    NotificationCenter.default.removeObserver(self, name:NSNotification.Name(rawValue:"name"), object:nil)


    方式二:使用通知队列发送通知

    NotificationQueue(通知队列)

    通知中心收到发送者发出的通知后,会立刻分发给监听者,但是如果把通知放在通知队列中,通知就可以等到某些特定时刻再发出,比如等到之前发出的通知在runloop中处理完,或者runloop空闲的时候。它就像通知中心的缓冲池,把一些不着急发出的通知存在通知队列中。

    存储在通知队列中的通知会以先进先出的方式发出。

    每个线程有一个默认的通知队列,它和通知中心关联着,是一个单例类。你也可以自己为线程或者通知中心创建多个通知队列。

    1.获取通知队列

    class var `default`: NotificationQueue { get }

    2.通知队列发送通知

    func enqueue(_ notification: Notification, postingStyle: NotificationQueue.PostingStyle, coalesceMask: NotificationQueue.NotificationCoalescing, forModes modes: [RunLoopMode]?)

    参数介绍:

    notification:要发送的通知消息对象

    postingStyle:发送方式,有三种:whenIdle(空闲时发送)、asap(尽快发送)、now(立即发送)

    coalesceMask:过滤通知方式,有三种:none(不合并)、onName(按通知的名字合并)、onSender(按通知的发送者合并)

    forModes:指定了某种特定runloop mode,一般为nil

    下面用通知队列发送一个消息,接收通知的代码就不写了,和方式一里面的一样:

    // 初始化消息通知对象

    let notification = Notification.init(name:Notification.Name(rawValue: "name"),

                                                      object:nil,

                                                    userInfo: userInfo)

    // 获取通知队列

    let nq = NotificationQueue.default

    // 发送通知

    nq.enqueue(notification,

    postingStyle:NotificationQueue.PostingStyle.asap,// 发送方式,立即发送

    coalesceMask:NotificationQueue.NotificationCoalescing.onName,// 根据通知名称过滤

    forModes:nil)

    具体使用哪种方式,要根据项目业务逻辑判断。如果通知发送时间间隔短,比较频繁,优先级不高,简易使用通知队列,因为有过滤功能,可以选择性过滤,减少频繁发送通知带来的额外开销。

    相关文章

      网友评论

          本文标题:Swift之正确使用通知

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