本篇讲解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. DevExpress控件学习总结(转)

    DevExpress控件学习总结   1.Navigation & Layout 1.1 Bar Manager 如果想在窗体或用户控件(user control)上添加工具条(bars)或弹 ...

  2. MySQL5.6生产库自动化安装部署

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://suifu.blog.51cto.com/9167728/1846671 自动化运 ...

  3. Delphi拷贝目录(含子目录)的方法

    要实现目录级的拷贝,可以利用Windows API函数ShFileOperation( ),其函数声明如下: WINSHELLAPI int WINAPI SHFileOperation( LPSHF ...

  4. jQuery 获取和设置type为hidden的input的值

    HTML代码 <input type="hidden" name="type" id="type" value="1&quo ...

  5. 部署statspack工具(一)

    禁用sga自动管理机制,分配比较小的数据缓冲区(30m)和共享池(70m)空间 1.1关闭SGA自动管理机制 查看是否开启了ASSM idle>show parameter sga; NAME  ...

  6. 关于aop:pointcut的expression配制说明及JoinPoint

    http://blog.csdn.net/wubai250/article/details/8102194 网上其它示例1:<aop:pointcut id="serviceMetho ...

  7. Xpath语法格式整理

    http://www.cnblogs.com/Loofah/archive/2012/05/10/2494036.html 经常在工作中会使用到XPath的相关知识,但每次总会在一些关键的地方不记得或 ...

  8. 第一篇:CUDA 6.0 安装及配置( WIN7 64位 / 英伟达G卡 / VS2010 )

    前言 本文讲解如何在VS 2010开发平台中搭建CUDA开发环境. 当前配置: 系统:WIN7 64位 开发平台:VS 2010 显卡:英伟达G卡 CUDA版本:6.0 若配置不同,请谨慎参考本文. ...

  9. 自动化测试框架中关于selenium api的二次封装

    不多说,直接看代码如下: #coding:utf-8 from selenium import webdriver from selenium.webdriver.common.action_chai ...

  10. ES1:Windows下安装ElasticSearch

    ElasticSearch(简称ES)是一个基于Lucene的分布式全文搜索服务器,本随笔演示在Windows安装ElasticSearch和用于管理ES的Head插件. ElasticSearch官 ...