ReactiveCocoa框架菜鸟入门(五)——信号的FlattenMap与Map

2023-12-14 14:38

本文主要是介绍ReactiveCocoa框架菜鸟入门(五)——信号的FlattenMap与Map,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章背景

本文是在阅读《ReactiveCocoa入门教程:第一部分》一文后,提出的一些补充。主要是比较深入的研究了信号(Signal)的FlattenMap与Map与Map方法。

读者应该至少了解信号的概念,以及信号的基本操作。

问题提出

有时候,我们需要把一个异步的API用信号的方式来表示。比如,点击登录按钮后异步的访问服务器,当获取到数据的时候再调用订阅者的处理方法。一个可能会出现的代码大概是这样:、

- (RACSignal *)signInSignal {
return [RACSignal createSignal:^RACDisposable *(id subscriber){[self.signInService signInWithUsername:self.usernameTextField.textpassword:self.passwordTextField.textcomplete:^(BOOL success){[subscriber sendNext:@(success)];[subscriber sendCompleted];}];return nil;
}];
}[[[self.signInButtonrac_signalForControlEvents:UIControlEventTouchUpInside]map:^id(id x){return [self signInSignal];}]subscribeNext:^(id x){NSLog(@"Sign in result: %@", x);}];

这样的代码并不能正常运行,原文给出的解决方案是把map方法换成flattenMap方法,但是却没有给出解释。在此专栏的上一篇文章,我们已经研究过了flattenMap的工作原理,并且明确了一点:map方法是基于flattenMap方法实现的。

再探FlattenMap与Map

在了解这两个方法的工作原理之前,我们不妨梳理一下思路。对于一个信号流(由若干个信号前后拼接而成)中的每一个信号而言,我们最关心它能传递出什么数据,就像我们只关心水龙头里面流出的是水还是石油一样。至于流入的数据,一定是上一个信号的流出数据。

然而,在之前的讨论中我们已经清楚,信号能流出什么样的数据,是在创建这个信号的决定的。也就是说,订阅者拿到的数据,取决于在创建信号的时候,我们制定的sendNext方法的参数。与现实生活不同的是,我们可以在水龙头之间添加过滤网来实现类似的功能。

在《ReactiveCocoa框架菜鸟入门——信号(Signal)详解》一文中,我们已经详细的查看了bind方法和flattenMap方法的代码和文档。

flattenMap方法,实际上是根据前一个信号传递进来的参数重新建立了一个信号,这个参数,可能会在创建信号的时候用到,也有可能根本用不到。比如在之前的例子中,我们其实调用了自定义的方法来创建信号。

之前提到过,我们关注一个信号能传递什么数据出来,那么调用了flattenMap方法创建的信号,会传出什么样的值呢?

答案是不知道!!!

因为flattenMap方法并不关心生成的信号会传递什么值,它只负责根据前一个信号的参数创建一个新的信号!
而至于这个信号会传递什么值,之前也提到过,是在创建信号的时候指定的。比如本文所举的例子中,我们自定义的信号会传递这样的值

[subscriber sendNext:@(success)];

理解了这一点之后,map方法就简单了。先看一下map方法的定义:

- (instancetype)map:(id (^)(id value))block {NSCParameterAssert(block != nil);Class class = self.class;return [[self flattenMap:^(id value) {return [class return:block(value)];}] setNameWithFormat:@"[%@] -map:", self.name];
}

这里的[class return:block(value)]方法实现了flattenMap方法的功能,他返回了一个信号。return:方法的代码实现有点长,有兴趣的读者可以自行查阅,这里就不具体分析,总结来说就是,这个信号传递的值讲是block(value)。

flattenMap方法和map方法都有一个带参数value的block作为这个方法的参数。不同的是,flattenMap方法通过调用block(value)来创建一个新的方法。它可以灵活的定义新创建的信号。而map方法,将会创建一个和原来一模一样的信号,只不过新的信号传递的值变为了block(value)。

总结一下,个人对map的理解是“变换”。map方法,根据原信号创建了一个新的信号,并且变换了信号的输出值。这两个信号具有明显的先后顺序关系。而flattenMap方法,直接生成了一个新的信号,这两个信号并没有先后顺序关系,属于同层次的平行关系。这也许就是为什么会被命名为flattenMap吧。

实践检验

回头看一看此前的例子之所以用map方法不行的原因在于,map方法创建的信号,接收了前一个信号传递的值,传出的值是[self signInSignal]的执行结果,即任然是一个信号,但是我们并不需要这个信号,我们需要的是这个信号的传出值。

使用flattenMap方法就可行的原因在于,flattenMap方法生成了一个新的信号,也就是我们调用[self signInSignal]的执行结果。这个信号的传出的值,在信号的创建过程中已经被定义。所以可以正常工作。

吐槽一句

非常感谢最初翻译出ReactiveCocoa教程的大牛,给了我们快速入门的机会。但是能力越大,责任也越大,简单一句flattenMap可以处理信号中的信号,是非常不负责任的,可能会影响无数的学习者。甚至原作者当时也没能完全理解flattenMap的工作原理以及和map方法之间的关系。我想,严谨、求真知,是对任何一门科学的基本尊重。包括软件工程。

这句话,也送给未来的自己!

原网址 http://blog.csdn.net/abc649395594/article/details/46552865

这篇关于ReactiveCocoa框架菜鸟入门(五)——信号的FlattenMap与Map的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/492915

相关文章

MySQL DQL从入门到精通

《MySQLDQL从入门到精通》通过DQL,我们可以从数据库中检索出所需的数据,进行各种复杂的数据分析和处理,本文将深入探讨MySQLDQL的各个方面,帮助你全面掌握这一重要技能,感兴趣的朋友跟随小... 目录一、DQL 基础:SELECT 语句入门二、数据过滤:WHERE 子句的使用三、结果排序:ORDE

Java中Map.Entry()含义及方法使用代码

《Java中Map.Entry()含义及方法使用代码》:本文主要介绍Java中Map.Entry()含义及方法使用的相关资料,Map.Entry是Java中Map的静态内部接口,用于表示键值对,其... 目录前言 Map.Entry作用核心方法常见使用场景1. 遍历 Map 的所有键值对2. 直接修改 Ma

全屋WiFi 7无死角! 华硕 RP-BE58无线信号放大器体验测评

《全屋WiFi7无死角!华硕RP-BE58无线信号放大器体验测评》家里网络总是有很多死角没有网,我决定入手一台支持Mesh组网的WiFi7路由系统以彻底解决网络覆盖问题,最终选择了一款功能非常... 自2023年WiFi 7技术标准(IEEE 802.11be)正式落地以来,这项第七代无线网络技术就以超高速

Java中JSON格式反序列化为Map且保证存取顺序一致的问题

《Java中JSON格式反序列化为Map且保证存取顺序一致的问题》:本文主要介绍Java中JSON格式反序列化为Map且保证存取顺序一致的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未... 目录背景问题解决方法总结背景做项目涉及两个微服务之间传数据时,需要提供方将Map类型的数据序列化为co

Python中OpenCV与Matplotlib的图像操作入门指南

《Python中OpenCV与Matplotlib的图像操作入门指南》:本文主要介绍Python中OpenCV与Matplotlib的图像操作指南,本文通过实例代码给大家介绍的非常详细,对大家的学... 目录一、环境准备二、图像的基本操作1. 图像读取、显示与保存 使用OpenCV操作2. 像素级操作3.

C++ HTTP框架推荐(特点及优势)

《C++HTTP框架推荐(特点及优势)》:本文主要介绍C++HTTP框架推荐的相关资料,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Crow2. Drogon3. Pistache4. cpp-httplib5. Beast (Boos

SpringBoot基础框架详解

《SpringBoot基础框架详解》SpringBoot开发目的是为了简化Spring应用的创建、运行、调试和部署等,使用SpringBoot可以不用或者只需要很少的Spring配置就可以让企业项目快... 目录SpringBoot基础 – 框架介绍1.SpringBoot介绍1.1 概述1.2 核心功能2

POI从入门到实战轻松完成EasyExcel使用及Excel导入导出功能

《POI从入门到实战轻松完成EasyExcel使用及Excel导入导出功能》ApachePOI是一个流行的Java库,用于处理MicrosoftOffice格式文件,提供丰富API来创建、读取和修改O... 目录前言:Apache POIEasyPoiEasyExcel一、EasyExcel1.1、核心特性

Java使用Stream流的Lambda语法进行List转Map的操作方式

《Java使用Stream流的Lambda语法进行List转Map的操作方式》:本文主要介绍Java使用Stream流的Lambda语法进行List转Map的操作方式,具有很好的参考价值,希望对大... 目录背景Stream流的Lambda语法应用实例1、定义要操作的UserDto2、ListChina编程转成M

Spring框架中@Lazy延迟加载原理和使用详解

《Spring框架中@Lazy延迟加载原理和使用详解》:本文主要介绍Spring框架中@Lazy延迟加载原理和使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、@Lazy延迟加载原理1.延迟加载原理1.1 @Lazy三种配置方法1.2 @Component