> 作为一个iOS开发小鱼,一直对RAC的使用垂涎不已,却一直没能深入学习,在项目闲暇的空档自娱自乐做个官方简介的中文翻译(结合google翻译).能力有限,如有谬误,还望指正海涵.以下为正文

ReactiveCocoa

框架代码地址:[https://github.com/ReactiveCocoa/ReactiveCocoa][1]

ReactiveCocoa(RAC)是一个Cocoa框架,灵感来自于函数响应式编程。它提供了实时地对数据流steams of values变化进行展示和响应的API。

目录:

  1. 介绍

  2. 示例:即时网络搜索

  3. Objective-C和Swift的支持情况

  4. RAC与Rx之间的关系

  5. 使用方法

  6. 操作步骤

如果你已经熟悉了函数响应式编程或基本了解了ReactiveCocoa,可以去文档文件夹里了解它的运行原理等信息。或者,直接进入我们的文档评论区,了解更多的相关API。

如果您有什么疑问,请先查看该问题在问题讨论区或StackOverflow上是否已经有了相关的讨论.如果没有的话,可随时提交给我们!

兼容性

这份RAC4文档适用于Swift 2.2.x. 关于Swift 1.2的支持请看RAC3.

介绍

ReactiveCocoa的灵感来自于函数响应式编程.

不同于就地即时地替换和修改可变变量的方案, RAC提供了“事件流”方案, 通过信号Signal和信号产生器的SignalProducer形式来展示和响应实时的数据值values的变化.

"事件流"统一了Cocoa里所有的非即时的事件处理模式,包括了:

  • 代理方法 Delegate methods

  • block回调 Callback blocks

  • 通知模式 NSNotifications

  • 控制动作和响应链事件 Control actions and responder chain events

  • 观察者模式 Key-value observing (KVO)

  • Futures and promises (不了解)

由于所有这些不同的机制可以通过相同的方式展示,容易发现将它们整合链接在一起,可以使代码更精简高效,同时使项目统一性更高.less spaghetti code and state to bridge the gap

更多的有关ReactiveCocoa概念信息,请参见框架概述。

实例:在线搜索,即时响应

比方说,你有一个文本输入框,当用户键入字段,你想即时对其进行搜索查询。

监控文本编辑

第一步是监控文本输入框的字段编辑情况, 专门对UITextField使用RAC扩展以实现这个需求:

let searchStrings = textField.rac_textSignal().toSignalProducer().map { text in text as! String }

以上代码给我们提供了一个能够发送字符串类型的值的信号产生器. (从Objective-C桥接扩展方法是相当必要的).

建立网络请求

我们需要随着字符串改变而同时执行网络请求. 同时, RAC提供的一个叫做NSURLSession的扩展可以满足这个需求:

let searchResults = searchStrings.flatMap(.Latest) { (query: String) -> SignalProducer<(NSData, NSURLResponse), NSError> inlet URLRequest = self.searchRequestWithEscapedQuery(query)return NSURLSession.sharedSession().rac_dataWithRequest(URLRequest)}.map { (data, URLResponse) -> String inlet string = String(data: data, encoding: NSUTF8StringEncoding)!return self.parseJSONResultsFromString(string)}.observeOn(UIScheduler())

这个将在主线程上将我们的字符串产生器转换成一个包含搜索结果的数组的产生器.(感谢UIScheduler).
此外,flatMap(.Latest) 确保了只有最后一个搜索操作能被执行.

如果用户在执行网络请求时候输入了其他的字节, 那么该网络请求将在下一个网络请求开始前被取消.

试想如果要自己写, 需要多少代码才能实现这个效果.

接收结果

这不会马上真正地执行, 因为如果要收取搜索结果,那么信号产生器必须先运行(这样可以防止无效运行).这很容易做到:

searchResults.startWithNext { results inprint("Search results: \(results)")
} 

这样, 我们要做的就是等待包含搜索结果的事件,然后将事件里的搜索结果打印到控制台,而这个打印操作可以很简单地用其他操作替代,比如说刷新屏幕上显示的各种视图.

故障处理

这个例子写到这一步,随便一个网络故障都有可能终止事件流.甚至可能会导致所有未来的查询操作都不会进行.

对此,我们需要决定当故障发生时应该如何处理.最快的解决办法就是先记录故障,然后忽略他们.

    .flatMap(.Latest) { (query: String) -> SignalProducer<(NSData,NSURLResponse), NSError> inlet URLRequest = self.searchRequestWithEscapedQuery(query)return NSURLSession.sharedSession().rac_dataWithRequest(URLRequest).flatMapError { error inprint("Network error occurred: \(error)")return SignalProducer.empty}}

我们可以用一个很有效的故障忽略办法,就是:通过用空事件流替换故障.

但在放弃之前多做几次尝试会更合适一些,而且有一个很方便的重试操作正对应这个需求.

我们的改进后的搜索结果产生器可以是这样的:

let searchResults = searchStrings.flatMap(.Latest) { (query: String) -> SignalProducer<(NSData, NSURLResponse), NSError> inlet URLRequest = self.searchRequestWithEscapedQuery(query)return NSURLSession.sharedSession().rac_dataWithRequest(URLRequest).retry(2).flatMapError { error inprint("Network error occurred: \(error)")return SignalProducer.empty}}.map { (data, URLResponse) -> String inlet string = String(data: data, encoding: NSUTF8StringEncoding)!return self.parseJSONResultsFromString(string)}.observeOn(UIScheduler())

减少网络请求的流量消耗

可以通过定期地执行实际的搜索操作, 以减少流量.

ReactiveCocoa里有一个我们能应用于搜索的操作:节流器throttle:

let searchStrings = textField.rac_textSignal().toSignalProducer().map { text in text as! String }.throttle(0.5, onScheduler: QueueScheduler.mainQueueScheduler)

这可以防止程序发送时间间隔少于0.5秒的数据请求.

如果要自己实现这个效果将会需要签名验证的状态significant state, 而且代码也会更加难以阅读! 但通过ReactiveCocoa, 我们只需要导入一个时间到我们的事件流里.

调试事件流

由于其本身的特性,一个流的堆栈可能有大量的构架, 其中大多通常可以使调试成为一件令人难搞的事情. 如下的插入附加作用side effect到流是一个比较基础的调试方法:

let searchString = textField.rac_textSignal().toSignalProducer().map { text in text as! String }.throttle(0.5, onScheduler: QueueScheduler.mainQueueScheduler).on(event: { print ($0) }) // the side effect

而以下操作将打印出这个流的事件, 同时不影响这个流的原本行为.信号产生器SignalProducer和信号*Signal都会自动为你运行打印操作:

let searchString = textField.rac_textSignal().toSignalProducer().map { text in text as! String }.throttle(0.5, onScheduler: QueueScheduler.mainQueueScheduler).logEvents()

更多信息和进阶操作,请查看调试技术文档.

Objective-C 和 Swift

虽然ReactiveCocoa最开始是一个基于Objective-C的框架, 但是从3.0版本开始,所有的主要功能开发都集中在Swift的API上.

在RAC里,Objective-C的API和Swift的API是完全分开的, 但是二者的转换是可以桥接的.这主要是为了兼容老的旧的ReactiveCocoa项目, 或者是使用了还没添加到Swift API 的Cocoa扩展的项目.

目前来说,Objective-C的API将继续存在并且得到支持,但不会得到很多的改进. 更多有关于API使用的信息,请查询我们的详细文档.

我们强烈建议所有新项目使用Swift API.

RAC与Rx之间的关系?

未完待续

ReactiveCocoa was originally inspired, and therefore heavily influenced, by Microsoft's Reactive Extensions (Rx) library.There are many ports of Rx, including RxSwift , but ReactiveCocoa is intentionally not a direct port.

Where RAC differs from Rx, it is usually to:

  • Create a simpler API

  • Address common sources of confusion

  • More closely match Cocoa conventions

The following are some of the concrete differences, along with their rationales.

ReactiveCocoa简介翻译相关推荐

  1. PhoneME简介(翻译)

    PhoneME简介(翻译) 作者:陈跃峰 出自: http://blog.csdn.net/mailbomb phoneME Feature software是一个优化了的Java ME架构.它的核心 ...

  2. ARM SIMD NEON 简介 (翻译自 Introducing NEON Development Article)

    目录 NEON简介 SIMD是什么? ARM SIMD 指令集 NEON是什么? NEON架构概览 支持的数据类型 NEON寄存器 NEON指令 NEON开发 汇编器 Intrinsics 自动向量化 ...

  3. ReactiveCocoa Documents 翻译(基于版本V2.5)

    1. 基本操作(Basic Operators) 描述 ReactiveCocoa 最常用的一些操作以及使用范例. 主要是如何运用 序列(sequences) 和 信号(signals) 的流操作. ...

  4. 最快让你上手ReactiveCocoa之基础篇

    前言 很多blog都说ReactiveCocoa好用,然后各种秀自己如何灵活运用ReactiveCocoa,但是感觉真正缺少的是一篇如何学习ReactiveCocoa的文章,小编看了很多篇都没看出怎么 ...

  5. ReactiveCocoa基础

    本文转载自最快让你上手ReactiveCocoa之基础篇,在此基础上稍作修改,欢迎交流. 有关对 ReactiveCocoa 的看法可以看一下唐巧的这篇ReactiveCocoa 讨论会 Reacti ...

  6. PyTorch C++ API libtorch 简介

    PyTorch C++ API libtorch 简介 翻译自 PyTorch 官方文档:https://pytorch.org/cppdocs/index.html#acknowledgements ...

  7. 【转】最快让你上手ReactiveCocoa之基础篇

    前言 很多blog都说ReactiveCocoa好用,然后各种秀自己如何灵活运用ReactiveCocoa,但是感觉真正缺少的是一篇如何学习ReactiveCocoa的文章,小编看了很多篇都没看出怎么 ...

  8. NS3_Tutorial 中文版: 第一章 简介

    [声明]允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任. http://yangfei1.blog.51cto.com/1471532/368585 转载 ...

  9. 经典神经网络论文超详细解读(八)——ResNeXt学习笔记(翻译+精读+代码复现)

    前言 今天我们一起来学习何恺明大神的又一经典之作: ResNeXt(<Aggregated Residual Transformations for Deep Neural Networks&g ...

  10. Quality-Estimation0 (翻译质量评价-使用 BERT 特征训练 QE 模型)

    简介 翻译质量评价(Quality Estimation,QE)是机器翻译领域中的一个子任务,大致可分为 Sentence-level QE,Word-level QE,Phrase-level QE ...

最新文章

  1. 网络上可供测试的Web Service
  2. 后缀数组的学习(三):SA数组实现代码分析
  3. java 链表 传递_java 链表 传递过程中的问题
  4. oracle9i在window server 2003 sp2 企业版突破1.7G内存限制
  5. 数字图像基础,论坛,算法库matlab,opencv,halcon
  6. 习题6-6 使用函数输出一个整数的逆序数 (20 分)
  7. 2019 Java发展趋势报告:Java老矣,Java正年轻
  8. 【官方搭建入门】JEECG 平台开发环境搭建必读
  9. Selenium WebDriver Api 知识梳理
  10. 汽车短视频大行其道,新能源汽车平台杉车网如何“领风骚”?
  11. python的range和linspace
  12. oracle9i监听自动断开,oracle连接超时自动断开问题
  13. python在线翻译小程序_Python 做一个翻译小程序
  14. Java开发微信公众号
  15. c语言里strcpy作用是什么,c语言中的strcpy是什么意思?
  16. 一年级下册计算机教学计划,人教版一年级数学下册教学计划
  17. 如何在Flatter中以正确的方式存储登录凭证
  18. 《Python自然语言处理》——1.1 语言计算:文本和词汇
  19. X64dbg-插件基本原理-加载顺序-概述-主目录
  20. AutoLine开源平台发布

热门文章

  1. 铁路订票系统的简单设计(转自云风)
  2. 3ds Max中的复制方式
  3. ad转3d视图快捷键_【技术干货】PCB工程师不得不看:超级实用AD常用快捷键总结...
  4. QCC3040---earbudUi module
  5. 英语的句号在c语言中是什么意思,英语标点符号的用法
  6. java学习 遇到的基本错误
  7. 神奇的泡泡java游戏,抖音挤泡泡游戏叫什么名字 抖音上很火的减压游戏介绍
  8. 狮子座与摩羯座 ---转载
  9. OPENGL中GLAD的代码实现过程
  10. linux网络配置文件,Linux下一块网卡设置多个IP地址