Swift之正确使用通知

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

概念一: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)

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容