iOS开发基础69-应用开发中的 Controller 间通信模式
1.iOS开发基础1-第一个iOS程序2.iOS开发基础2-基础控件3.iOS开发基础6-懒加载、Plist 文件操作、字典转模型、自定义 View 详解4.iOS开发基础5-UIButton5.iOS开发基础4-图像资源6.iOS开发基础3-UIImage7.iOS开发基础14-KVC的应用与底层逻辑8.iOS开发基础13-深入理解 UITableView(二)9.iOS开发基础12-深入理解UITableView(一)10.iOS开发基础11-屏幕适配、Autolayout及 Masonry 框架11.iOS开发基础10-UIButton内边距和图片拉伸模式12.iOS开发基础9-提示框(UIAlertController)13.iOS开发基础8-UIScrollView14.iOS开发基础7-自定义构造方法、layoutSubviews、Xib文件与自定义View15.iOS开发基础30-UITabBarController16.iOS开发基础29-触摸事件及手势识别17.iOS开发基础28-数据存储与沙盒机制18.iOS开发基础27-导航控制器入栈与出栈机制及微博个人详情页19.iOS开发基础26-空20.iOS开发基础25-ARC和MRC深入探析21.iOS开发基础24-UIPickerView、UITextField、KVC、UIDatePicker、控制器及导航控制器22.iOS开发基础23-iOS开发中的Info.plist、UIApplication及其Delegate、UIWindow详解23.iOS开发基础22-键盘通知在iOS开发中的应用24.iOS开发基础21-深入理解通知、代理、KVO和Block在iOS开发中的应用25.iOS开发基础20-UITableView的全局及局部刷新、左滑操作与批量删除26.iOS开发基础19-深入理解和实现不等高的 UITableViewCell27.iOS开发基础18-深入理解 Objective-C Runtime 机制28.iOS开发基础16-使用 `NSTimer` 时避免内存泄露的技巧和最佳实践29.iOS开发基础15-KVO的应用与底层逻辑30.iOS开发基础65-iPad 开发指南31.iOS开发基础64-二维码32.iOS开发基础63-AVFoundation/MediaPlayer33.iOS开发基础62-音频播放34.iOS开发基础61-通讯录35.iOS开发基础60-传感器36.iOS开发基础59-内存优化37.iOS开发基础58-支付宝集成指南38.iOS开发基础57-换肤功能与静态库开发指南39.iOS开发基础56-UIDynamic物理引擎40.iOS开发基础55-利用 UIWindow 实现快速滚动到界面顶部41.iOS开发基础54-CoreLocation42.iOS开发基础53-MapKit 框架43.iOS开发基础47-iOS键盘44.iOS开发基础46-数据安全与HTTPS保护详解45.iOS开发基础45-UIWebview46.iOS开发基础44-网络编程之NSURLSession&AFN47.iOS开发基础43-CocoaPods48.iOS开发基础42-网络编程之文件下载与处理49.iOS开发基础41-网络编程之JSON和XML50.iOS开发基础40-网络编程之NSURLConnection51.iOS开发基础39-RunLoop52.iOS开发基础38-多线程之多图片下载及缓存处理53.iOS开发基础37-多线程之NSOperation54.iOS开发基础36-多线程之GCD55.iOS开发基础35-多线程之NSThread56.iOS开发基础34-多线程57.iOS开发基础33-核心动画(二)58.iOS开发基础33-核心动画(一)59.iOS开发基础32-Quartz2D(二)60.iOS开发基础32-Quartz2D(一)61.iOS开发基础31-Modal 与 Push 详解62.iOS开发基础76-iOS 开发中的属性修饰符详解63.iOS开发基础75-iOS开发中的Block深度解析64.iOS开发基础74-Swift他来了65.iOS开发基础73-24种性能优化技巧66.iOS开发基础72-Xcode 7 升级后的问题与解决方案详解67.iOS开发基础71-应用中的 StatusBar 详解68.iOS开发基础70-TCP与UDP
69.iOS开发基础69-应用开发中的 Controller 间通信模式
70.iOS开发基础68-图片轮播71.iOS开发基础67-流水布局相册缩放72.iOS开发基础66-UISearchBar 控件指南73.iOS开发基础78-iOS 国际化在开发 iOS 应用时,我们经常需要让不同的 controllers 之间进行通信,而不希望它们之间过于耦合。为此,我们通常会使用以下三种模式来实现通信:
- 委托(delegation)
- 通知中心(Notification Center)
- 键值观察(Key Value Observing, KVO)
模式概述
这三种模式提供了对象之间传递事件而不需要紧密耦合的方法,让不同的对象可以通知彼此某些事件的发生。下面我们详细描述每种模式的特点、优缺点以及适用场景。
一、委托(Delegation)
原理
委托模式类似于“代理”模式,一个对象(delegator)定义了一个协议(protocol),该协议中包含了一系列方法。这些方法由另一个对象(delegate)实现,并在特定时间由 delegator 调用。当某些事件发生时,delegator 通过调用 delegate 实现的方法来通知其事件的发生。
优点
- 严格的语法:在编译过程中,如果代理对象没有实现协议中的方法,将会有编译警告或错误。
- 明确的控制流程:你可以清晰地跟踪程序的控制流程,因为代码是明确调用的。
- 不需要第三方对象:通信过程无需第三方对象参与。
- 支持多协议:一个类可以实现多个协议,每个协议有不同的 delegate。
- 支持返回值:delegate 可以向 delegator 提供反馈。
缺点
- 需要定义大量代码:必须定义协议,声明 delegate 属性,并实现相关方法。
- 内存管理问题:在释放代理对象时,需要将 delegate 属性设置为 nil 以避免内存泄漏和崩溃。
- 难以实现一对多:一般情况下,委托模式是用于一对一通信。
适用场景
委托模式通常用于父子关系的对象之间(如控制器和视图)或需要返回值的场景。适合需要较强控制和明确定义的交互。
二、通知中心(Notification Center)
原理
通知中心是一种发布/订阅模型的实现。一些对象可以向通知中心发布通知,多个订阅者可以订阅并响应这些通知。
优点
- 简单的实现方式:不需要编写过多代码。
- 支持一对多通信:一个通知可以同时被多个对象接收。
- 传递上下文对象:通过 userInfo 参数,通知中心可以传递自定义的信息。
缺点
- 缺乏编译期检查:编译时不会检查通知是否能够正确处理。
- 调试复杂:因为通知机制是松散耦合的,追踪和调试通知的控制流程比较复杂。
- 需要第三方对象:通知中心作为中介管理通信过程。
- 无法获得反馈:通知发布者无法获得通知接收者的反馈。
适用场景
通知中心适用于需要在整个应用中广播消息的场景,特别是需要多对象响应同一事件的情况。如全局配置变化、用户登录状态变化等。
三、键值观察(Key Value Observing, KVO)
原理
通过键值观察,某个对象可以观察另一个对象的属性变化。对象 A 可以注册自身为对象 B 某属性的观察者,当该属性变化时,KVO 机制自动通知对象 A。
优点
- 自动同步:KVO 是实现对象间同步的简便方法,例如 model 和 view 之间的同步。
- 无侵入性:不需要改变被观察对象的实现。
- 传递属性变化信息:KVO 能提供被观察属性的最新值和之前值。
- 支持嵌套观察:通过 key paths,可以观察嵌套对象的属性。
- 抽象化:不需要额外代码来允许观察值被观察。
缺点
- 字符串定义:观察的属性通过字符串定义,编译时不会检查该字符串是否有效。
- 重构风险:属性的变更会导致观察代码不可用。
- 复杂管理:观察多个属性需要复杂的管理代码。
- 需要移除观察者:在对象释放时,需要移除所有观察。
适用场景
KVO 适用于需要属性变化通知的场景,特别是 model 和 view 之间的数据绑定和同步。
效率和适用性分析
效率
- 委托 的效率最高,因为它是直接的方法调用,且支持返回值。
- 通知中心 则效率相对较低,因为它实现了一对多的广播机制。
- KVO 的效率在特定场景下(如属性变化)非常高,但它需要处理大量的回调,不适用于大量属性和频繁变化的情况。
适用性
- 委托:用于一对一的强交互场景,特别是父子关系的对象之间。
- 通知中心:用于全局消息传递和一对多通知的情况。
- KVO:用于属性变化的监控和对象间的数据同步。
结论
这三种通信模式各有优缺点和适用场景。具体选择哪种模式,需要根据实际需求和场景进行决定:
- 对于属性层的事件,尤其是 model 和 view 的同步,使用 KVO 是最清晰且高效的。
- 对于大多数控制器间的通信,尤其是需要返回值和带有强交互的场景,使用委托模式是最合适的。
- 对于需要广播消息的场景,尤其是应用中多个对象需要响应的事件,使用通知中心更加方便。
在实际开发中,开发者应灵活运用这些模式,根据具体需求和场景选择最合适的通信方式,这样才能编写出高效、可维护的代码。
将来的你会感谢今天如此努力的你!
版权声明:本文为博主原创文章,未经博主允许不得转载。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!