ReactiveSwift源码解析(十二) MutableProperty基本代码实现
前两篇博客我们分别聊了ReactiveSwift框架中的负责标记对象的生命周期的类Lifetime以及负责原子性操作的Atomic类的具体代码实现。前两篇博客之所以聊Lifetime以及Atomic的代码实现,就是为了今天这篇博客做铺垫的。在Property以及MutableProperty的代码实现中我们会用到Lifetime以及Atomic。本篇博客我们就来仔细的探讨一下Property以及MutableProperty的代码实现。
因为MutableProperty用处更多,而且MutableProperty的代码实现比Property要复杂一些,那么本篇博客我们就以MutableProperty为例来看一下其代码实现。之所以在本篇博客中聊Property的代码实现,在于之前我们已经陆陆续续的聊了Event、Observer、Signal、SignalProducer、Lifetime以及Atomic的代码实现。而Property就是在上述基础上的进一步封装。
下方我们先来看一下MutableProperty的一个简单的使用示例,然后根据该示例来看一下MutableProperty的基本代码实现。看完基本代码实现后,下方也会根据相应的示例来看一下Property的一些常用的扩展方法的具体实现。
一、MutableProperty的简单应用示例
我们还是由简到繁的步骤,本部分我们会给出两个MutableProperty使用的简单示例。一个是关于Property中的Signal的,另一个是关于Property中的SignalProducer的。下部分内容我们会给据该部分的示例以及示例的输出结果来分析MutableProperty具体的代码实现。
1、MutableProperty中的Signal对象
下方示例展示了MutableProperty中的signal对象的使用方式。下方是对该段代码的解释:
首先我们创建了一个可变的属性对象mutableProperty,该属性的初始值为1。
然后给该属性对象中的signal对象添加一个Value事件的观察者,在该观察者中输出所观察到的值Value。当mutableProperty所关联的值被修改时,就会执行该观察者所对应的事件闭包。
接着我们就修改mutableProperty对象的value的值,将该值修改成10。然后就获取该值进行输出

上述截图的最下方就是该示例的输出结果,从该结果中我们不难看出,当可变属性被赋值时Value事件的闭包体就会执行。而通过withValue以及value属性就可以获取到该值。在获取值时不会执行上述闭包事件。
2、MutableProperty中的SignalProducer对象
下方是MutableProperty中SignalProducer对象的简单使用示例。下方代码示例与上方的代码片段类似,输出结果也差不多,只不过SignalProducer对象的Value事件会先输出当前MutableProperty对象中所存储的值。当修改MutableProperty中所存储的值时,就会执行SignalProducer中内置的Signal的Value事件。具体如下所示:

二、MutableProperty类的基本实现
看完第一部分的MutableProperty的简单的使用方式,接下来我们就来看一下MutableProperty类的基本实现。MutableProperty类的基本实现是比较简单的主要包括Signal、Observer对象的初始化,还有Lifetime对象的初始化,以及Atomic对象的初始化操作。而MutableProperty类的核心方法都在其扩展中,稍后会介绍到。接下来我们先看一下MutableProperty中的属性、构造器以及基本方法。
1、MutableProperty的属性以及构造器
下方代码片段就是MutableProperty中的核心属性以及主要的构造器,如果详细的看了之前的博客的话,下方这几个属性并不陌生,接下来我们来一一介绍:
token和lifetime属性负责标记MutableProperty的生命周期,关于Lifetime的代码实现与具体工作方式,请移步于《Lifetime代码实现》。
signal与observer则负责在修改value值时给观察者发送事件的,Signal与Observer的具体代码实现以及工作方式在之前的博客中也详细的介绍过来,在此不做过多赘述了。
atomic属性则负责原子操作的,从下方的atomic的属性类型我们可以看出该原子操作添加的是递归锁。关于Atomic的详细内容我们之前的博客也介绍过了,详情请移步于《Atomic的代码实现以及其中的Defer延迟、Posix互斥锁、递归锁》。
value属性是一个计算属性,其中的get和set方法主要是调用atomic属性中的相应的方法进行值的获取和赋值操作。
producer属性也是一个计算属性,其中返回了一个SignalProducer类的对象。从代码中我们不难看出该producer对象中的signal对象与MutableProperty中的signal对象进行了桥接,也就是说,该producer属性可以收到来自MutableProperty中信号量的事件。关于SignalProducer的详细内容请移步于《SignalProducer的基本实现及使用方式》。
MutableProperty的构造器就是对上述这些未被初始化的属性进行初始化了。其中需要注意的一点是Atomic对象的初始化,在atomic属性初始化是,将observer属性的Value事件的执行块赋值给了didSet闭包。所以当atomic中的value值被修改后就会调用observer的send(value)事件,这一点在MutableProperty中还是比较重要的。

根据上述代码的属性以及构造器,我们不难画出下方这个简图。该图给出了上述属性的各种关系,以及当MutableProperty的Value值被修改时,SentValue事件的走向,具体如下所示。

2、MutableProperty类中基本方法的代码实现
接下来我们就来看一下MutableProperty类中其他方法的实现。下方就是MutableProperty类中剩余的方法,下方的方法比较简单,主要是对atomic属性中相关方法的二次封装,具体如下所示:

今天的博客就先到这儿,下篇博客我们会挑一些MutableProperty的扩展方法中比较重要和基础的方法进行介绍。Property以及MutableProperty中的其他扩展方法大部分都是在SignalProducer以及Signal的基础上所建立起来的,功能也是大同小异,在此就不做过多赘述了。
上述代码github分享地址:https://github.com/lizelu/TipSwiftForRac。
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #ffffff }
span.s1 { }
ReactiveSwift源码解析(十二) MutableProperty基本代码实现的更多相关文章
- ReactiveSwift源码解析(十) Lifetime代码实现
为了之后博客的进行,本篇博客我们就来聊一下ReactiveSwift框架中的Lifetime类的具体实现.从Lifetime这个名字中我们就这道,就是生命周期.在ReactiveSwift中使用Lif ...
- ReactiveSwift源码解析(五) SignalProtocol的observe()、Map、Filter延展实现
上篇博客我们对Signal的基本实现以及Signal的面向协议扩展进行了介绍, 详细内容请移步于<Signal中的静态属性静态方法以及面向协议扩展>.并且聊了Signal的所有的g功能扩展 ...
- ReactiveSwift源码解析(三) Signal代码的基本实现
上篇博客我们详细的聊了ReactiveSwift源码中的Bag容器,详情请参见<ReactiveSwift源码解析之Bag容器>.本篇博客我们就来聊一下信号量,也就是Signal的的几种状 ...
- Cwinux源码解析(二)
我在我的个人博客上发表了第二篇解析文章.欢迎各位读者批评指正. Cwinux源码解析(二)
- # Volley源码解析(二) 没有缓存的情况下直接走网络请求源码分析#
Volley源码解析(二) 没有缓存的情况下直接走网络请求源码分析 Volley源码一共40多个类和接口.除去一些工具类的实现,核心代码只有20多个类.所以相对来说分析起来没有那么吃力.但是要想分析透 ...
- OpenJDK源码研究笔记(十二):JDBC中的元数据,数据库元数据(DatabaseMetaData),参数元数据(ParameterMetaData),结果集元数据(ResultSetMetaDa
元数据最本质.最抽象的定义为:data about data (关于数据的数据).它是一种广泛存在的现象,在许多领域有其具体的定义和应用. JDBC中的元数据,有数据库元数据(DatabaseMeta ...
- Spring事务源码解析(二)获取增强
在上一篇文章@EnableTransactionManagement注解解析中,我们搭建了源码阅读的环境,以及解析了开启Spring事务功能的注解@EnableTransactionManagemen ...
- Netty 源码解析(二):Netty 的 Channel
本文首发于微信公众号[猿灯塔],转载引用请说明出处 接下来的时间灯塔君持续更新Netty系列一共九篇 Netty源码解析(一):开始 当前:Netty 源码解析(二): Netty 的 Channel ...
- AOP源码解析之二-创建AOP代理前传,获取AOP信息
AOP源码解析之二-创建AOP代理前传,获取AOP信息. 上篇文章对AOP的基本概念说清楚了,那么接下来的AOP还剩下两个大的步骤获取定义的AOP信息,生成代理对象扔到beanFactory中. 本篇 ...
随机推荐
- CJOJ 1131 机器分配 / Luogu 2066 机器分配 (动态规划)
CJOJ 1131 机器分配 / Luogu 2066 机器分配 (动态规划) Description Luogu: 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国 ...
- Domains域
一个域是一个criteria(度量标准)列表,每个criterion(标准尺度)是一个三元列表或者元组:field_name,operator,value. field_name(str) 当前模型的 ...
- Jenkins中的一些问题解决(~~不断更新~~)
请使用ctrl+F,查询页面中你需要查找的错误信息(注意空格的输入) 1.错误"error fetching remote repo origin" 本地有多个sshkey,导致构 ...
- 白话ASP.NET MVC之一:Url 路由
好久没有写关于ASP.NET MVC的东西了,虽然<ASP.NET MVC4框架揭秘>已经完完整整的看完一遍,但是感觉和一锅粥差不多,没什么可写的,因为我自己不理解,也就写不出来.现在开始 ...
- CentOS 下mysql ERROR&n…
CentOS 下mysql ERROR 1045: Access denied for user: 'root@localhost' (Using password: NO) 描述:在操作数据库时会出 ...
- 用u盘装系统,进入bios后没有usb启动项怎么办
开机按DEL进入BIOS(现在还这么说吧,不同的主板进入方法不太一样),找到BOOT选项. 选择Boot mood:legacy support(引导模式,逻辑支持) boot priorty:leg ...
- 怎么把系统装进u盘(ultraiso)
首先要下载一个叫ultraiso的软件.可以在百度中搜索此软件下载.下载后安装,安装后打开软件,如图所示. 点击左上角的文件选项,在弹出的菜单中,点击打开选项,打开一个你要装进U盘的 ...
- TASKCTL产品功能清单-转载
功能分类 功能描述 一级 二级 关系 调度控制 作业依赖关系调度 作业依赖关系调度是调度最基本的功能,指作业间具有顺序的运行,比如:a.b.c三个作业,只有当a完成后才运行b,b完成才能运行c 作业并 ...
- vue指令v-once示例解析
只渲染元素和组件一次.随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过.这可以用于优化更新性能. <!-- 单个元素 --> <span v-once>This ...
- 再起航,我的学习笔记之JavaScript设计模式06(抽象工厂模式)
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前两 ...