本篇讲解swift中通知的用法

前言

通知作为传递事件和数据的载体,在使用中是不受限制的。由于忘记移除某个通知的监听,会造成很多潜在的问题,这些问题在测试中是很难被发现的。但这不是我们这篇文章探讨的主题。

我曾见过,有的团队为了管理通知,开发了一个类似于NotificationManager的类,所有通知的添加移除都通过这个类进行管理,通过打印通知数组就能很清楚的看到添加了哪些通知,以及这些通知被绑定在那些对象之上,这是一个很好地思路。

发通知

swift中发通知的函数原型是这样的:

open func post(name aName: NSNotification.Name, object anObject: Any?, userInfo aUserInfo: [AnyHashable : Any]? = nil)

除了name之外,其他参数跟OC的没什么区别,name的主要作用就是作为通知的唯一标识。在OC中,这个name是一个最普通的字符串,这就导致了开发中的乱用的问题。很多人为了管理这些通知字符串想出了很多办法,比如:

  • 把这些字符串放到一个或几个文件中
  • 写一个类根据不同功能提供不同的字符串,这个是比较推荐的写法,也和本篇中讲解的用法很像

Notification.Name

在上边发通知的函数中,我们发现name的类型是Notification.Name,那么这个Notification.Name是什么鬼呢?

extension NSNotification {

    public struct Name : RawRepresentable, Equatable, Hashable, Comparable {

        public init(_ rawValue: String)

        public init(rawValue: String)
}
}

通过上边的原型函数可以得出如下结论:

  • NameNSNotification中的一个成员,类型是结构体
  • 通过一个字符串进行初始化

可以使用下边的代码创建Notification.Name

let notificationName = Notification.Name(rawValue: "com.xxx")

高级用法

extension Notification.Name {
/// Used as a namespace for all `URLSessionTask` related notifications.
public struct Task {
/// Posted when a `URLSessionTask` is resumed. The notification `object` contains the resumed `URLSessionTask`.
public static let DidResume = Notification.Name(rawValue: "org.alamofire.notification.name.task.didResume") /// Posted when a `URLSessionTask` is suspended. The notification `object` contains the suspended `URLSessionTask`.
public static let DidSuspend = Notification.Name(rawValue: "org.alamofire.notification.name.task.didSuspend") /// Posted when a `URLSessionTask` is cancelled. The notification `object` contains the cancelled `URLSessionTask`.
public static let DidCancel = Notification.Name(rawValue: "org.alamofire.notification.name.task.didCancel") /// Posted when a `URLSessionTask` is completed. The notification `object` contains the completed `URLSessionTask`.
public static let DidComplete = Notification.Name(rawValue: "org.alamofire.notification.name.task.didComplete")
}
}

上边代码做的唯一一件事情就是给通知的name分类,通过扩展了一个Task这样的结构体,把跟task相关的通知都绑定在这个Task上,因此,在代码中就可以这么使用:

NotificationCenter.default.post(
name: Notification.Name.Task.DidComplete,
object: strongSelf,
userInfo: [Notification.Key.Task: task]
)

Notification.Name.Task.DidComplete表达的非常清晰,一般都能知道是task请求完成之后的通知。

上边的代码中还出现了[Notification.Key.Task: task]这行代码,:

extension Notification {
/// Used as a namespace for all `Notification` user info dictionary keys.
public struct Key {
/// User info dictionary key representing the `URLSessionTask` associated with the notification.
public static let Task = "org.alamofire.notification.key.task"
}
}

扩展了Notification,新增了一个Key结构体,这个结构体用于取出通知中的userInfo。

总结

通知用起来还是比较简单的,在实际开发中,可以参考Alamofire中的Notifications.swift这个文件的设计就行,按照自己的业务创建不同的结构体就可以了。

由于知识水平有限,如有错误,还望指出

链接

Alamofire源码解读系列(一)之概述和使用 简书博客园

Alamofire源码解读系列(二)之错误处理(AFError) 简书博客园

Alamofire源码解读系列(三)之通知处理(Notification)的更多相关文章

  1. Alamofire源码解读系列(四)之参数编码(ParameterEncoding)

    本篇讲解参数编码的内容 前言 我们在开发中发的每一个请求都是通过URLRequest来进行封装的,可以通过一个URL生成URLRequest.那么如果我有一个参数字典,这个参数字典又是如何从客户端传递 ...

  2. Alamofire源码解读系列(五)之结果封装(Result)

    本篇讲解Result的封装 前言 有时候,我们会根据现实中的事物来对程序中的某个业务关系进行抽象,这句话很难理解.在Alamofire中,使用Response来描述请求后的结果.我们都知道Alamof ...

  3. Alamofire源码解读系列(六)之Task代理(TaskDelegate)

    本篇介绍Task代理(TaskDelegate.swift) 前言 我相信可能有80%的同学使用AFNetworking或者Alamofire处理网络事件,并且这两个框架都提供了丰富的功能,我也相信很 ...

  4. Alamofire源码解读系列(七)之网络监控(NetworkReachabilityManager)

    Alamofire源码解读系列(七)之网络监控(NetworkReachabilityManager) 本篇主要讲解iOS开发中的网络监控 前言 在开发中,有时候我们需要获取这些信息: 手机是否联网 ...

  5. Alamofire源码解读系列(八)之安全策略(ServerTrustPolicy)

    本篇主要讲解Alamofire中安全验证代码 前言 作为开发人员,理解HTTPS的原理和应用算是一项基本技能.HTTPS目前来说是非常安全的,但仍然有大量的公司还在使用HTTP.其实HTTPS也并不是 ...

  6. Alamofire源码解读系列(九)之响应封装(Response)

    本篇主要带来Alamofire中Response的解读 前言 在每篇文章的前言部分,我都会把我认为的本篇最重要的内容提前讲一下.我更想同大家分享这些顶级框架在设计和编码层次究竟有哪些过人的地方?当然, ...

  7. Alamofire源码解读系列(十)之序列化(ResponseSerialization)

    本篇主要讲解Alamofire中如何把服务器返回的数据序列化 前言 和前边的文章不同, 在这一篇中,我想从程序的设计层次上解读ResponseSerialization这个文件.更直观的去探讨该功能是 ...

  8. Alamofire源码解读系列(十一)之多表单(MultipartFormData)

    本篇讲解跟上传数据相关的多表单 前言 我相信应该有不少的开发者不明白多表单是怎么一回事,然而事实上,多表单确实很简单.试想一下,如果有多个不同类型的文件(png/txt/mp3/pdf等等)需要上传给 ...

  9. Alamofire源码解读系列(十二)之时间轴(Timeline)

    本篇带来Alamofire中关于Timeline的一些思路 前言 Timeline翻译后的意思是时间轴,可以表示一个事件从开始到结束的时间节点.时间轴的概念能够应用在很多地方,比如说微博的主页就是一个 ...

随机推荐

  1. Core Data需求

    大家都在讨论怎么使用Core Data,但是什么时候用到Core Data,这好像是大家很少讨论的问题 我们使用Core Data ,主要用来存储两种类型的数据:固定的数据,和 可能变化的数据. 1. ...

  2. IDEA Show Line Number

    刚开始用IDEA,经常发现右侧没有显示行号,然后去右键选一下,就显现了 一直没有留意这个现象,刚用vim想删几行数据代码,突然发现没有行号了 明明记得刚刚才右键显示了的 好吧,有行号用着比较顺心了.. ...

  3. inheritprototype原型继承封装及综合继承最简实例

    1.inheritprototype.js ;(function(){    var s = {        inheritObject:function(o){//对象继承封装           ...

  4. Log4j的扩展-支持设置最大日志数量的DailyRollingFileAppender

    Log4j现在已经被大家熟知了,所有细节都可以在网上查到,Log4j支持Appender,其中DailyRollingFileAppender是被经常用到的Appender之一.在讨论今天的主题之前, ...

  5. PHP实现验证码图片

    <?php header("Content-type: image/png"); session_start(); $authnum = ''; $str = 'abcdef ...

  6. 必备的实用jQuery代码段(1)

    1. 如何正确地使用toggleClass: //切换(toggle)类允许你根据某个类的 //是否存在来添加或是删除该类. //这种情况下有些开发者使用: a.hasClass('blueButto ...

  7. QT第三天学习

    回顾: 布局: 绝对位置法: 手工布局:QLayout 可视化布局:设计器 VB MFC JAVA C# cocos QT信号和槽 ---------------------------------- ...

  8. ORA-01555经典错误

    --创建undo表空间时固定表空间的大小 sys@TDB112>create undo tablespace undo_small 2  datafile'/u01/app/oracle/ora ...

  9. SVG在网页中的四种使用方式

    1,直接打开simple.svg <svg xmlns="http://www.w3.org/2000/svg" width="200" height=& ...

  10. SDWebImage源码解读之SDWebImageManager

    第九篇 前言 SDWebImageManager是SDWebImage中最核心的类了,但是源代码确是非常简单的.之所以能做到这一点,都归功于功能的良好分类. 有了SDWebImageManager这个 ...