zoukankan      html  css  js  c++  java
  • Alamofire源码解读系列(三)之通知处理(Notification)

    本篇讲解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) 简书博客园

  • 相关阅读:
    GDI+ 读取jpg图片每个像素的值
    OpenCV 闭合轮廓检测
    OpenCV 求外接矩形以及旋转角度
    新编黑客攻防从入门到精通
    精通HTML5 + CSS3+JavaScript网页设计
    SolidWorks 2016中文版完全自学手册
    零基础轻松学MySQL 5.7
    R数据科学
    软件工程(工业和信息化普通高等教育“十二五”规划教材)
    World/Excel/PowerPoint 2013商务办公三合一
  • 原文地址:https://www.cnblogs.com/machao/p/6484360.html
Copyright © 2011-2022 走看看