利用属性观察器实现数据绑定
数据绑定的多种实现方法

想法
- 在
didSet
方法里,通知观察者 - 支持多个观察者
- 支持取下监听
- 无需显式取消监听,在销毁时自动取消监听
代码
public final class Box<T> {public typealias Listenr = (T) -> Voidprivate var observers: NSHashTable<AnyObject>private var managerKey: Void?/// 真正存储的值public var value: T {didSet {observers.allObjects.forEach { (observer) inlet block = objc_getAssociatedObject(observer, &managerKey)if let block1 = block as? Listenr {block1(value)}}}}/// 初始化方法////// - Parameter value: 用来被绑定的valuepublic init(_ value: T) {self.value = valueobservers = NSHashTable<AnyObject>.weakObjects()}/// 添加观察者。target在销毁时,会自动移除观察,不会有内存泄漏。////// - Parameters:/// - target: 观察者,变化时,会通知到它/// - block: 发生变化时,需要执行的操作。block为nil,取消绑定public func bind(target: AnyObject, block: Listenr?) {observers.add(target)objc_setAssociatedObject(target, &managerKey, block, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)block?(value)if block == nil {observers.remove(target)}}
}
几点说明
- 使用了关联对象,把对监听对象的响应作为
observer
的一个属性。这样子,在observer
销毁时,自然会取消监听 - 使用了
weak NSHashTable
来存储observers
- 在初次绑定时,通知了
observer
当前值
使用例子
let box = Box<Int>.init(4)let observer2 = ObserverExample.init()let observer3 = ObserverExample.init()box.bind(target: observer2) { [unowned observer2 ] (value) inobserver2.value = value}box.bind(target: observer3) { [unowned observer3 ] (value) inobserver3.value = value}// 去掉 observer2 对box 的监听box.bind(target: observer2, block: nil)box.value = -9XCTAssertEqual(box.value, observer3.value)XCTAssertNotEqual(box.value, observer2.value)
参考
- MVVM in Practice - RWDevCon Session - raywenderlich.com
转载于:https://www.cnblogs.com/huahuahu/p/li-yong-shu-xing-guan-cha-qi-shi-xian-shu-ju-bang-.html
利用属性观察器实现数据绑定相关推荐
- 一起认识下浏览器的5种观察器
"图片懒加载",这个词语想必大家再熟悉不过了.传统的实现方法是,监听scroll事件,获取img元素相对于视口的顶点位置el.getBoundingClientRect().top ...
- 技术图文:Python的属性装饰器详解
背景 我们在以前的一篇图文 Python基础 – Task10. 类与对象 中介绍过利用property()方法既能保护类的封装特性,又能让开发者可以使用"对象.属性"的方式操作类 ...
- Adobe Reader 文档无法签名_手把手教你如何利用PDF阅读器压缩PDF文档
众所周知,PDF格式文本.格式.字体.颜色.分辨率.链接及图形图像.声音.动态影像等所有的信息封装在一个特殊的整合文件中.这个优点也导致我们工作学习上接触到的PDF文档体积都不小,非常影响阅读体验和邮 ...
- DirectX11 With Windows SDK--17 利用几何着色器实现公告板效果
DirectX11 With Windows SDK--17 利用几何着色器实现公告板效果 原文:DirectX11 With Windows SDK--17 利用几何着色器实现公告板效果 前言 上一 ...
- ssm影城项目_影场与属性访问器界面
ssm影城项目 卡尔·迪亚(Carl Dea)最近跟踪了我的一篇名为" 保存内存"的博客文章! 为属性使用阴影字段 . 在他的博客中,他建议使用称为"属性访问器" ...
- threejs 影子属性_影子场vs.属性访问器接口第2轮
threejs 影子属性 如果你们还没有注意到Dirk Lemmerman和我之间的(轻松) 摊牌 ,那么让我快速提及一下我们是如何做到这一点的. 首先,Dirk创建了JavaFX技巧23:" ...
- listview属性_属性提取器:获取ListView即时更新其元素的最佳方法
listview属性 这篇文章是关于如何处理JavaFX ListViews和TableViews的,以及如何通过这些控件了解所包含元素的更改内容. 我想知道为什么在相关书籍中没有找到关于以下模式的任 ...
- 影场与属性访问器界面
卡尔·迪亚(Carl Dea)最近跟踪了我的一篇名为" 保存内存"的博客文章! 为属性使用阴影字段 . 在他的博客中,他建议使用一个称为"属性访问器"的接口来消 ...
- 影子场vs.属性访问器接口第2轮
如果你们还没有注意到Dirk Lemmerman和我之间的(轻松) 对决 ,那么让我快速提及一下我们是如何做到这一点的. 首先,Dirk创建了JavaFX技巧23:" 为属性保存内存阴影字段 ...
最新文章
- 获取本地 qt_好消息,可以使用 VS 进行 Qt 的跨平台开发啦!
- 【OpenCV】使用projectPoints实现透视图到俯视图的变化效果
- 59. 螺旋矩阵 II(模拟)
- 数据结构-栈之二进制转十进制和八进制
- react全局状态管理_rxv: 在React中用Vue3的reactivity包实现状态管理。
- auto.js小案例
- 计算机开机引导的结果是,电脑开机显示引导媒体是怎么回事
- python使用pkg包_Python deb-pkg-tools包_程序模块 - PyPI - Python中文网
- 使用CreateProcess函数运行其他程序
- 基于vue-cli 将webpack3 升级到 webpack4 配置
- js正则替换html字符串,js正则找出字符串的内容,并替换内容
- android 拼图小游戏
- iOS手势识别的工作原理
- 禁忌搜索算法(现代优化计算方法)
- C# 温故而知新:Stream篇(五)
- Linux 28 岁了,我们总结了 28 个不为人知的事实
- 实施MES系统的成功率只有50%,你知道为什么吗?
- AI高考的信息检索策略
- LearnOpenGL学习笔记—高级光照 09:SSAO
- 【软件设计师】知识点与试题
热门文章
- 2017 码云最火开源项目 TOP 50,你用过哪些?
- meshgrid 的使用方法
- 在线文档显示组件 FlexPaper
- RDL(C) Report Design Step by Step 2: SubReport
- c语言风景日历制作系统,初学,C语言日历制作
- 机器视觉系统中相机镜头选型技巧_工业相机在机器视觉系统中的地位和作用
- python读json文件太大github_GitHub上最火的开源项目是啥|JSON文件实战处理
- 一个寄存器有几个字节_STM32f103ZET6 学习资料 (连载2 寄存器的操作界限)
- Markdown--绘制流程图(flowchart)
- 设定pic单片机端口为输入_PIC单片机IO端口的软件/硬件可靠性使用方法讨论