Swift通知与KVO对比分析:何时该用哪种机制?

第一章:Swift通知与KVO机制概述

在Swift开发中,通知(Notification)与键值观测(Key-Value Observing, KVO)是实现对象间通信的重要机制。它们允许对象在状态变化时通知其他对象,而无需彼此直接引用,从而降低耦合度,提升代码的可维护性。

通知机制

通知基于观察者模式,通过 NotificationCenter 实现跨对象的消息广播。任意对象可发送通知,其他对象注册为观察者以接收特定名称的通知。 例如,发送一个自定义通知:
// 发送通知
NotificationCenter.default.post(
    name: Notification.Name("UserLoggedIn"),
    object: nil,
    userInfo: ["username": "john_doe"]
)
观察者需在适当时机添加监听并实现回调:
// 添加观察者
NotificationCenter.default.addObserver(
    self,
    selector: #selector(handleLogin),
    name: Notification.Name("UserLoggedIn"),
    object: nil
)

@objc func handleLogin(notification: Notification) {
    if let username = notification.userInfo?["username"] as? String {
        print("用户已登录:$username)")
    }
}
注意:必须在对象销毁前移除观察者,避免崩溃:
deinit {
    NotificationCenter.default.removeObserver(self)
}

KVO机制

KVO用于监听对象属性的变化,要求被观察的类继承自 NSObject,且属性使用 @objc dynamic 修饰。
  • 使用 observe(_:options:changeHandler:) 方法注册观察
  • 在回调中处理属性变化
  • 系统自动触发观察事件
机制适用场景优点缺点
通知多对多通信松耦合,跨层级通信难以追踪发送源,易内存泄漏
KVO属性变更监听实时响应属性变化语法复杂,仅限 NSObject 子类

第二章:Swift通知机制深入解析

2.1 通知中心原理与NSNotificationCenter详解

NSNotificationCenter 是 iOS 中实现对象间解耦通信的核心机制,基于观察者模式,允许对象订阅、发送和接收通知。
基本使用方式
通过 defaultCenter 获取全局通知中心实例,注册观察者并监听特定名称的通知:

[[NSNotificationCenter defaultCenter] 
    addObserver:self 
    selector:@selector(handleNotification:) 
    name:@"DataUpdated" 
    object:nil];
上述代码中,self 作为观察者监听名为 DataUpdated 的通知,当通知触发时调用 handleNotification: 方法处理逻辑。
通知的发送与移除
发送通知使用 postNotificationName:object: 方法:

[[NSNotificationCenter defaultCenter] 
    postNotificationName:@"DataUpdated" 
    object:self];
通知在对象销毁前必须移除,避免崩溃:
  • 使用 addObserver:selector:name:object: 注册后,需在 dealloc 中 removeObserver:
  • block 形式注册可自动管理生命周期

2.2 定义和发送自定义通知的实践方法

在现代应用架构中,自定义通知机制是实现用户触达与系统联动的核心手段。通过定义结构化消息体,开发者可灵活控制通知内容与行为。
通知结构设计
一个典型的自定义通知应包含标题、内容、类型及附加数据字段。推荐使用 JSON 格式封装:
{
  "title": "系统提醒",
  "body": "您的订单已发货",
  "type": "order_update",
  "data": {
    "order_id": "123456",
    "action_url": "/orders/123456"
  }
}
上述 payload 中,type 字段用于客户端路由处理,data 携带上下文信息,便于跳转或后续操作。
发送流程实现
通过 HTTP 客户端调用通知服务 API,需设置认证头并指定内容类型:
  • 使用 POST 方法提交到 /api/notify
  • Header 包含 Authorization 与 Content-Type: application/json
  • 异步发送以避免主流程阻塞

2.3 观察者注册与移除的正确模式(iOS 9+)

在 iOS 9 及更高版本中,使用 Key-Value Observing (KVO) 时必须遵循新的 addObserver:forKeyPath:options:context: 与 removeObserver:forKeyPath: 配对模式,确保内存安全与观察者生命周期可控。
观察者的注册
注册观察者需保证后续能精确移除,避免崩溃。典型实现如下:

[self addObserver:self.viewModel
       forKeyPath:@"model.updated"
          options:NSKeyValueObservingOptionNew
          context:&MyContext];
其中,context 使用唯一地址(如静态变量地址)可防止不同观察者间的键路径冲突,提升安全性。
观察者的移除
无论观察是否触发,都应在 dealloc 或视图消失前显式移除:
  • 必须与 addObserver 调用配对
  • context 参数需保持一致

- (void)dealloc {
    [self removeObserver:self.viewModel forKeyPath:@"model.updated" context:&MyContext];
}
未正确移除会导致野指针或重复释放,引发运行时崩溃。

2.4 使用Swift扩展增强通知的安全性与可维护性

在Swift中,通过扩展(extension)为Notification.Name添加类型安全的静态常量,可有效避免字符串硬编码带来的拼写错误和维护难题。
定义类型安全的通知名称
extension Notification.Name {
    static let userLoggedIn = Notification.Name("UserLoggedIn")
    static let dataSyncCompleted = Notification.Name("DataSyncCompleted")
}
该扩展将散落在各处的字符串通知名称集中管理,提升可读性和重构支持。一旦名称变更,仅需修改一处。
优势分析
  • 避免运行时因拼写错误导致的通知失效
  • 支持Xcode自动补全与编译时检查
  • 便于统一管理应用级通知事件
结合访问控制(如private或internal),还可限制通知的作用域,进一步增强模块化设计的健壮性。

2.5 通知生命周期管理与常见内存泄漏规避

在现代应用开发中,通知系统的生命周期管理直接影响应用的性能和稳定性。若未正确管理观察者注册与注销,极易引发内存泄漏。
注册与注销的配对原则
确保每个 addObserver 调用都有对应的 removeObserver 调用,推荐在组件销毁时统一清理:

NotificationCenter.default.addObserver(
    self,
    selector: #selector(handleUpdate),
    name: .dataUpdated,
    object: nil
)

deinit {
    NotificationCenter.default.removeObserver(self)
}
上述代码中,deinit 确保对象释放前移除所有通知监听,避免悬空引用。
常见泄漏场景与规避策略
  • 使用字符串名称注册通知时易拼写错误,建议封装为静态常量
  • 闭包形式监听需注意强引用循环,可使用 [weak self] 捕获
  • iOS 9+ 支持基于 block 的监听,自动管理生命周期更安全

第三章:通知机制的实际应用场景

3.1 跨层级组件通信中的通知使用案例

在复杂前端架构中,跨层级组件常面临直接依赖导致的耦合问题。通知机制通过发布-订阅模式解耦组件间通信。
事件总线实现方案
class EventBus {
  constructor() {
    this.events = {};
  }
  on(event, callback) {
    if (!this.events[event]) this.events[event] = [];
    this.events[event].push(callback);
  }
  emit(event, data) {
    if (this.events[event]) {
      this.events[event].forEach(cb => cb(data));
    }
  }
}
上述代码构建了一个轻量级事件总线。on 方法注册监听,emit 触发通知。任意深度的子组件均可通过实例订阅或发送消息,实现跨层级数据传递。
典型应用场景
  • 全局状态变更通知(如用户登录)
  • 表单验证结果广播
  • UI 主题切换响应

3.2 多模块解耦设计中的通知架构实践

在复杂系统中,多模块间的低耦合通信至关重要。事件驱动架构通过异步通知机制实现模块解耦,提升系统可维护性与扩展性。
事件发布-订阅模型
采用消息中间件(如Kafka、RabbitMQ)作为事件总线,模块间通过主题进行通信:

type EventPublisher struct {
    broker MessageBroker
}

func (p *EventPublisher) Publish(event DomainEvent) error {
    // 将领域事件序列化并发送至指定主题
    topic := event.Type()
    data, _ := json.Marshal(event)
    return p.broker.Send(topic, data) // 异步投递
}
该模式下,发布者无需感知订阅者存在,实现时间与空间解耦。
典型应用场景
  • 订单创建后触发库存扣减
  • 用户注册后发送欢迎邮件
  • 日志审计模块监听关键操作事件
消息可靠性保障
机制说明
持久化消息写入磁盘防止丢失
ACK确认消费者处理完成后显式应答
重试队列失败消息进入死信队列供后续分析

3.3 响应系统事件与后台任务完成的通知处理

在现代应用架构中,及时响应系统事件并处理后台任务的完成通知是保障用户体验和数据一致性的关键环节。通过监听事件总线或使用回调机制,系统能够在任务完成后触发相应动作。
事件监听与回调注册
应用通常通过注册监听器来捕获后台任务状态变更:
type TaskNotifier struct {
    listeners []func(taskID string, status string)
}

func (n *TaskNotifier) RegisterListener(f func(string, string)) {
    n.listeners = append(n.listeners, f)
}

func (n *TaskNotifier) Notify(taskID string, status string) {
    for _, listener := range n.listeners {
        listener(taskID, status)
    }
}
上述代码实现了一个简单的通知器,允许多个回调函数订阅任务状态变化。Notify 方法遍历所有注册的监听器并传递任务 ID 与最新状态。
典型应用场景
  • 文件上传完成后刷新UI
  • 定时同步任务结束后的数据更新
  • 推送执行结果至消息队列

第四章:通知机制的最佳实践与性能优化

4.1 通知队列与线程调度的合理配置

在高并发系统中,通知队列与线程调度的协同设计直接影响系统的响应延迟与吞吐能力。合理的资源配置可避免线程饥饿与消息积压。
队列类型选择
根据业务场景选择合适的阻塞队列:
  • ArrayBlockingQueue:有界队列,防止资源耗尽
  • LinkedBlockingQueue:无界队列,适用于突发流量
  • PriorityBlockingQueue:支持优先级调度
线程池参数配置示例
new ThreadPoolExecutor(
    8,                    // 核心线程数
    16,                   // 最大线程数
    60L,                  // 空闲线程存活时间
    TimeUnit.SECONDS,
    new ArrayBlockingQueue<>(1000) // 任务队列容量
);
核心线程保持常驻,最大线程应对峰值,队列缓冲突发请求,避免拒绝服务。
调度策略优化
参数建议值说明
corePoolSizeCPU核心数匹配I/O与计算平衡
queueCapacity1000~5000防止内存溢出

4.2 弱引用观察者与闭包回调的结合使用

在响应式架构中,弱引用观察者能有效避免循环引用,而闭包回调则提供灵活的事件响应机制。二者结合可在保证内存安全的同时实现高度解耦。
核心实现模式

class Observer {
    weak var target: AnyObject?
    let callback: (Notification) -> Void

    init(target: AnyObject, callback: @escaping (Notification) -> Void) {
        self.target = target
        self.callback = callback
    }

    func notify(_ notification: Notification) {
        guard let _ = target else { return }
        callback(notification)
    }
}
上述代码中,weak var target 确保不增加引用计数,闭包 callback 捕获上下文但不持有目标对象,防止内存泄漏。
应用场景优势
  • 适用于UI组件监听模型变化
  • 支持运行时动态注册与注销回调
  • 提升多模块间通信的灵活性

4.3 避免过度广播:通知频率与负载控制

在分布式系统中,频繁的状态广播易引发网络拥塞与节点过载。合理控制通知频率是保障系统稳定性的关键。
指数退避重试机制
当检测到网络延迟或失败时,采用指数退避策略可有效缓解广播风暴:
// 指数退避发送通知
func backoffBroadcast(attempt int) time.Duration {
    return time.Second * time.Duration(math.Pow(2, float64(attempt)))
}
该函数根据尝试次数返回递增的等待时间,避免短时间内大量重复广播。
消息合并与节流控制
通过滑动时间窗口对变更事件进行批量处理:
  • 设定最大广播间隔(如500ms)
  • 在窗口期内合并多次状态更新
  • 使用节流器限制单位时间内的通知数量
负载感知调节策略
节点负载等级广播频率上限(次/秒)
低(<30% CPU)10
中(30%-70%)5
高(>70%)1
系统依据实时资源使用动态调整广播行为,实现性能与一致性的平衡。

4.4 单元测试中对通知逻辑的模拟与验证

在单元测试中,通知逻辑通常依赖外部服务(如邮件、消息队列),直接调用会影响测试的隔离性与执行效率。因此,需通过模拟(Mock)机制替代真实通知行为。
使用 Mock 验证通知调用
以 Go 语言为例,结合 testify/mock 库对通知接口进行模拟:

type MockNotifier struct {
    mock.Mock
}

func (m *MockNotifier) Send(message string) error {
    args := m.Called(message)
    return args.Error(0)
}
上述代码定义了 MockNotifier,其 Send 方法可被测试代码控制返回值,并记录调用情况。
验证通知行为
在测试中设置期望并断言:
  • 调用次数:确保通知仅在特定条件下触发;
  • 参数内容:验证传递的消息是否符合业务规则;
  • 错误处理:模拟发送失败路径,检验容错逻辑。

第五章:总结与选型建议

技术栈选型的核心考量因素
在微服务架构落地过程中,技术栈的选型需综合评估团队能力、系统规模与运维成本。例如,Go 语言因其高并发和低延迟特性,适用于高性能网关开发:

package main

import (
    "net/http"
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    r.GET("/health", func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{"status": "ok"})
    })
    r.Run(":8080")
}
该示例展示了使用 Gin 框架快速构建健康检查接口,适合边缘服务快速部署。
主流框架对比与适用场景
不同业务场景对框架的要求差异显著,以下为常见后端技术栈对比:
技术栈吞吐量(req/s)学习曲线典型应用场景
Spring Boot8,500中等企业级管理系统
Go + Gin28,000较陡高并发API网关
Node.js + Express6,200平缓I/O密集型中间层
团队能力匹配建议
对于初创团队,推荐采用 Node.js 快速验证业务逻辑;中大型系统应优先考虑 Go 或 Java,以保障长期可维护性。某电商平台在流量增长至百万级日活后,将用户中心从 Node.js 迁移至 Go,QPS 提升 3.2 倍,服务器成本降低 40%。
swift-iOS安全的KVO操作解决由于添加了KVO忘记移除或者多次移除导致的崩溃问题 iOS安全的KVO操作,解决由于添加了KVO忘记移除,或者多次移除导致的崩溃问题 立即下载

相关推荐

swift-一句话使用KVO使用完无需自己移除KVO

一句话使用KVO,使用完无需自己移除KVO

Swift - KVO

KVO(Key-Value Observing)是Cocoa 中公认的最强大的特性之一,但是同时它也以“烂到家”的API 和极其难用著称。和属性观察不同,KVO 的目的并不是为当前类的属性提供一个钩子方法,而是为了其他不同实例对当前的某个属性(严格来说是 keypath)进行监听。其他实例可以充当一个订阅者的角色,当被监听的属性发生变化时,订阅者将得到通知。 这是一个功能很强大的属性,通过KVO 我们可以实现很多松耦合的结构,是代码更加灵活和强大,像通过监听model 的值来自动更新UI 的绑定这样的工作,

HumorousGhost 1609

Swift5.2 KVO

Swift5.2 KVO

swift 中的KVO用法

KVO 属性观察器

任意门 5468

专访高性能计算专家赵开勇:无人机/机器人开发实战,如何优化深度学习?

从能够自主飞行的无人机,到能和小朋友玩物体识别等游戏的机器人,极客们对智能设备追求没有止境。除了轻巧的体积、超长的续航,更重要的是要有一个智能的“大脑”,来实现人类能够想得到的人机交互,或者智能化的自主决策和行为动作,毫无疑问强大的深度学习能力不可或缺。那么,拒绝束缚人类想象力的嵌入式智能设备,其开发工作需要什么样的环境和工具?开发者进行相关开发的可行思路是什么?近日,优快云记者就此专访了智能设...

happytofly的博客 3509

STM32F103xx / STM32F429VET6最小系统原理图

心血来潮想试一下STM32F4系列和F1系列在编程上有什么差别,手头没有开发板,本着能勤俭节约的原则自己先做一块看看能不能成,看了一下STM32F429VET6的芯片在F429xx中最便宜,对照着数据手册绘制了原理图画了PCB,目前打板中,焊接完如果跑不通回来修改文章。这里我们可以看到,VDD是标准工作电压,VDDA是模拟工作电压,且VDDA必须与VDD等电位,VBAT是备份工作电压,一般接纽扣电池电源,如果存在VREF+引脚,则要求VDDA-VREF+ < 1.2V。截图下来比较糊,不知道为什么。

m0_51294753的博客 1万+

【iOS KVO(上)实现过程】

利用runtime的API动态生成一个子类,并让实例对象的isa指向这个全新的子类当修改实例变量对象的属性时候,在全新子类的set方法中会调用Foundation的_NSSetXXXValueAndNotify函数调用原来的setter:内部会触发监听器的监听方法在调用的时候,会自动生成并注册一个该对象(被观察的对象)对应类的子类,取名NSKVONotify_Class,并且将该对象的isa指针指向这个新的类。

weixin_61639290的博客 1401

《全连接到卷积神经网络:图像识别的演变历程》

这篇文章会从传统全连接层面临的困境说起,揭示卷积神经网络(CNN)成为图像识别核心动力的原因,探究其背后蕴含的设计思想与技术创新。但是回顾历史,CNN的出现提醒我们:技术的突破往往是由对自然规律的模仿和重新构建得来的。也许,当机器真的学会“像人一样看世界”的时候,它们的“眼睛”早就超过生物视觉的限制了。例如,用5×5的核处理224×224的输入时,只要25个参数(而不是全连接那种百万级的)。* 局部性:网络的底层只需留意局部的地方(像边缘、纹理这样的地方),不用管那些全局像素之间复杂的关系。

2401_82434295的博客 674

关于swift中KVO的简单使用

简单的kvo,描述的不太好,仅供初学者参考

weixin_36185308的博客 593

SAR型ADC的电荷重分配技术解析

本文深入解析了SAR型ADC的核心技术——电荷重分配。通过类比“猜数字”游戏,阐述了其逐次逼近的工作原理,并重点剖析了电容阵列如何实现高速、低功耗的模数转换。文章还探讨了该技术在速度、能效及集成度方面的优势,并指出了电容匹配精度等实际挑战,为嵌入式与物联网设备中的ADC选型与应用提供了实用指南。

nnn11的博客 907

Win11 系统下 VisualStudio2022 配置点云库 PCL1.11.1

安装完成之后打开文件夹E:\PCL 1.11.1\3rdParty\OpenNI2双击 并选择路径 (E:\PCL 1.11.1\3rdParty\OpenNI2) 安装即可全部安装完成之后,将pcl-1.11.1-pdb-msvc2019-win64.zip解压后的 .pdb文件拷贝到(E:\PCL 1.11.1\bin)中设置环境变量:到此,环境变量配置完成。

qq_53545309的博客 1126

【Swift通知使用全攻略】:掌握iOS开发中NSNotification的5大核心技巧

掌握Swift通知用法,轻松实现iOS应用中的消息传递。详解NSNotification在页面通信、状态更新等场景的5大核心技巧,涵盖 addObserver、postNotificationName 等关键方法,提升代码解耦与响应效率。实用指南值得收藏。

PixelFlow的博客 741

【用unity实现100个游戏之7】实现一个类《杀戮尖塔》的卡牌回合制游戏(附项目源码)

【用unity实现100个游戏之7】实现一个类《杀戮尖塔》的卡牌回合制游戏(附项目源码)

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 1万+

Swift中 addObserver 你真的会用吗?深入解析通知监听的陷阱与优化

掌握Swift通知用法,避开addObserver常见陷阱。详解NSNotificationCenter在页面通信、事件监听中的正确实践,涵盖弱引用、iOS 9后API适配与Swift 5优化方案,提升代码稳定性与性能,值得收藏。

FastSolve的博客 1185

【OD统一考试(B卷)】比赛的冠亚季军,Python 解答

比赛的规则是 0 号和 1 号比赛,2 号和 3 号比赛,以此类推,每一轮,相邻的运动员进行比赛,获胜的进入下一轮,实力值大的获胜,实力值相等的情况,id 小的情况下获胜,轮空的直接进入下一轮。第一轮比赛,id 为 0 实力值为 2 的运动员和 id 为 1 实力值为 3 的运动员比赛, 1 号胜出进入下一轮争夺冠亚军,id 为 2 的运动员和 id 为 3 的运动员比赛,3 号胜出进入下一轮争夺冠亚军;2 号与 0 号,比赛进行季军的争夺,2 号实力值为 4,0 号实力值 2,故 2 号胜出,得季军。

梦想橡皮擦,专栏100例写作模式先行者,现象级专栏 《Python 爬虫 100 例》作者、《滚雪球学 Python 专栏》原创者 1万+

C#跨平台制图新纪元:Mapsui,一库在手,地图我有

深入学习Mapsui的渲染机制,定制属于你的地图样式,无论是颜色、图标还是文字,都可以随心所欲。

java专栏 1457

KVO原理分析介绍

????????关注后回复“进群”,拉你进程序员交流群????????作者丨搜狐视频 刘壮来源丨搜狐技术产品(ID:sohu-tech)本文字数:5154字预计阅读时间:15分钟KVO原理分析介绍KVO全称K...

<sdffdsfsdfdfs>sfsfsfsdfsdffds</sdfsDS>Fsd 355

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

iOS UIKit - 通知机制

通知机制的5中方式: Target/Action Delegation NSNotification KVO Block 一、使用步骤 1.Target/Action [self.btn addTarget:self action:@selector(test:) forControlEvents:UIControlEventTouchUpInside];} -(voi

Seal_Shile的博客 449

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

iOS - KVO底层原理分析

文章目录简单复习一下KVO注册观察者观察者发生变化时会调的方法移除观察者小demoKVO的本质person1的isa指向改变,指向NSKVONotifying_MJPerson类关于NSKVONotifying_MJPerson类注总结 KVO全称:Key-Value Observing, 俗称“健值监听”,可以用于监听某个对象属性值的改变 简单复习一下KVO 注册观察者 addObserver:forKeyPath:options:context 参数含义: observer:观察者,监听属性变化的对

weixin_45841522的博客 512

详解:RxSwift-KVO底层探索(上)

收录:原文地址 KVO在我们实际开发之中运用非常之多,很多开发者都知道原理!但是这些原理是如何来的,一般都是浅尝辄止。这个篇章我会从 Swift 入手分析,探索KVO底层源码.希望让读者真正掌握这一块底层,知其然而知其所以然! KVO简介 首先我们从KVO的三部曲开始 // 1: 添加观察 person.addObserver(self, forKeyPath: "name", option...

D_猿员的博客 339

OC底层探索(十六) KVO底层原理

OC底层文章汇总 KVO全称KeyValueObserving,是苹果提供的一套事件通知机制。允许对象监听另一个对象特定属性的改变,并在改变时接收到事件。由于KVO的实现机制,所以对属性才会发生作用,一般继承自NSObject的对象都默认支持KVO。 KVO和NSNotificationCenter都是iOS中观察者模式的一种实现。区别在于,相对于被观察者和观察者之间的关系,KVO是一对一的,而不一对多的。KVO对被监听对象无侵入性,不需要修改其内部代码即可实现监听。 KVO可以监听单个属性的变化,也可.

正在注销账号的博客 601

iOS底层探索之KVO(五)—FBKVOController分析

回顾 在前面的几篇博客中,已经介绍了KVO的基本使用,如何自定义 KVO,那么本篇博客将分析一下FBKVOController这个优秀的KVO三方库。 FBKVOController是一个函数式编程实现,不用移除观察者者。 1. FBKVOController简单介绍 FBKVOController是Facebook开源的一个基于系统KVO实现的框架。支持Objective-C和Swift语言。 GitHub地址 键值观察是一种特别有用的技术,用于在模型-视图-控制器应用程序中的层之间进行通信。KV

俊而不逊的博客 1272

Apple官文中的KVO 与 FBKVOController

前言 本文将主要介绍以下内容: 详细列出Apple官文中KVO的注意事项(Apple KVO相关的引用皆摘自Apple官文)。 介绍FBKVOController,以及它如何避免系统提供的KVO坑点。 Apple官文中的KVO 关于KVO 官方文档: Key-value observing is a mechanism that allows objects to be notif...

weixin_30652879的博客 272

iOS 代理与通知,kvc和kvo的区别

通知通知需要有一个通知中心:NSNotificationCenter,自定义通知的话需要给一个名字,然后监听。优点:通知的发送者和接受者都不需要知道对方。可以指定接收通知的具体方法。通知名可以是任何字符串。缺点:较键值观察(KVO)需要多点代码,在删掉前必须移除监听者。协议通过setDelegate来设置代理对象,最典型的例子是常用的TableView.优点:支持它的类有详尽...

weixin_34026276的博客 176
上一篇: Swift 中 Core Data 到底该怎么用?90%开发者忽略的5个最佳实践
下一篇: 你以为懂了Kotlin基础类型?这7个冷门知识点可能让你大跌眼镜
codetrick
博客等级 码龄17年 151粉丝 1991原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值