IOS学习笔记: Notifications通知机制

这篇博客详细介绍了iOS中的Notifications通知机制,包括基本概念、实现方法和代码实例。作者通过机场取行李的比喻解释了通知的工作原理,强调了Notification与UserNotification的区别。文章还展示了如何注册监听者、发送通知以及处理通知的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IOS学习笔记: Notifications

本人IOS小白一枚,如理解有误,请各位大神补充/斧正

基本概念

什么是Notification? 英语八级的你一定知道这是通知的意思,那什么是通知呢?
概念上,IOS的通知机制,允许一个对象通过“广播通知”的方式,告知其他的对象(通知的监听者)“有事情发生了!!!”,这些监听者在接收到通知以后,可以做出相应的处理。
从这段鄙人很不专业的描述中可以看出:

  1. 通知机制可以实现由一个对象负责监听事件,由其他若干对象来负责事件的具体处理。(分工,降低单个对象复杂度)
  2. 通知的发送者,发送了通知A,但不知道谁会监听到通知,也不知道会被如何处理; 通知的接受者,只知道接收到通知A,也知道自己要怎么处理这个通知,但是不知道是谁发送的通知。(模块独立性)

备注: 本文讨论的是Notification,是对象之间的一种交流机制,而不是UserNotification(设置推送) , 注意区别!


实现方法:

要实现通知的功能,至少要有以下几个要素:

  1. 通知: Notification
  2. 通知发送者: 将通知放到通知中转站上
  3. 通知中转站: NotificationCenter
  4. 通知监听者: observer

这样讲还是比较模糊,也说不清楚,举一个小栗子吧!

很多人都坐过灰机,知道下灰机之后第一件事情就是取行李(shang’ce’suo),那么我们就以取行李为例吧!

我们先来捋一捋机场取行李的过程:

1. 机场工作人员拿起一个行李,贴上唯一的身份码,把行李放到传送带上
2. 我在传送带旁边等待自己的行李
3. 乘客 一旦发现自己的行李(身份码与自己手中条子上的一样),执行相应的操作( 取行李)

在这个过程中不同的对象分别充当了一下角色:

  • 行李: 通知(Notification)
  • 唯一身份码: 通知名称(必须唯一,用于识别不同的通知)
  • 传送带工作人员: 通知发送者(负责post Notification)
  • 行李传送带: 通知中转站(NotificationCenter)
  • 乘客: 通知监听者(observer)

代码实现:

接下来我们把取行李这个过程用代码来模拟一下,具体看看通知机制的代码实现

如图,先创建两个swift文件,分别命名为Passager.swift和AirportStaff.swift,分别代表乘客和机组成员两个类。
这里写图片描述

备注:以下是代码展示,后面将对一些代码细节进行回顾。

Passager.swift中

import Foundation
import UIKit

//定义乘客类
class Passager {
    //乘客名字
    let name: String
    init(name: String) {
        self.name = name
    }

    func waittingForLuggage(_ luggageName: Notification.Name) {
    //将对象注册成为名为Notification.Name的通知的observer,监听该通知
        NotificationCenter.default.addObserver(forName: luggageName, object: nil, queue: OperationQueue.main) {
            _ in 
            //如果接收到通知,输出信息
            print("\(self.name): Get my luggage")
        }
    }      
}

AirportStaff.swift中

import Foundation
import UIKit

class AirportStaff {
    func postLuggage(_ name: Notification.Name) {
        print("airportStaff: I put \(name.rawValue) on the Conveyor")
        //创建一个名为name的通知,放入NotificationCenter
        NotificationCenter.default.post(name: name, object: nil)
    }
}

最后,在AppDelegate.swift文件的
application(_ didFinishLaunchingWithOptions launchOptions: )函数中进行测试

先在class外面定义两个全局变量:

//创建和接收通知都需要通过唯一的通知名,因此首先定义两个通知名
let xiaomingLuggage = Notification.Name(rawValue: "XiaoMingLuggage")
let laowangLuggage = Notification.Name(rawValue: "LaoWangLuggage")

然后,修改AppDelegate.swift文件中的
application(_ didFinishLaunchingWithOptions launchOptions: )函数为:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        //1. 创建三个对象: 机组人员(发送者),乘客小明和乘客老王(observer)
        let airPortStaff = AirportStaff()
        let xiaoMing = Passager(name: "XiaoMing")
        let laoWang =  Passager(name: "LaoWan")


        //2. 小明和老王分别等待各自的行李(注册小明和老王两个对象为observer,等待通知)
        //现在,这两个对象都在监听Notification上的通知
        xiaoMing.waittingForLuggage(xiaomingLuggage)
        laoWang.waittingForLuggage(laowangLuggage)

        //3. 机组人员将小明的行李放上传送带
        //两个人都能看到,但是只有小明做出反应
        airPortStaff.postLuggage(xiaomingLuggage)
        //4. 机组人员将老王的行李放上传送带
        //两个人都能看到,但是只有老王做出反应
        airPortStaff.postLuggage(laowangLuggage)

        return true
    }

测试输出


airportStaff: I put XiaoMingLuggage on the Conveyor
XiaoMing: Get my luggage

airportStaff: I put LaoWangLuggage on the Conveyor
LaoWan: Get my luggage


从输出中可以看到,当发送通知“xiaomingLuggage”,只有小明做出了反应,因为小明是通知“xiaomingLuggage”的唯一监听者; 相应地,当发送通知“laowangLuggage”,只有老王做出了反应,因为老王是通知“laowangLuggage”的唯一监听者


代码细节回顾:

以下代码将当前对象(方法的调用者)注册为默认NotificationCenter的监听者(observer),并指定当前对象监听名为luggageName的通知

NotificationCenter.default.addObserver(forName: luggageName, object: nil, queue: OperationQueue.main)

1) NotificationCenter: 是一个类,可以理解为是“通知的中转站”或者“通知展示区”,发送者将通知发送到上面,而监听者监听上面的通知,等待自己想要的通知
2)default变量:是NotificationCenter类的一个类变量。.default代表使用默认的NotificationCenter。当然也可以不使用默认的NotificationCenter,而选择创建自己的NotificationCenter这里不做赘述。
3)调用addObserver(forName:object:queue:using:)方法,注册当前对象为NotificationCenter的监听者()

  • forName: 接受一个Notification.Name类型的参数,表示通知的名称(必须是唯一的),用于指定要监听哪一个通知。
  • object: 接受一个对象(泛类型),表示只接收指定对象的通知。值为nil代表不指定特定的对象
  • queue: 接受一个队列,协调多线程操作。程序中的QueueOperation.main表示多线程
  • using: 接受一个closure,指定接收到通知后要执行的操作

4)建立并初始化“通知名称”对象:

Notification.Name(rawValue: String)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值