信号(signal)— RACSignal类

1. 一般表示将来有数据传递,只要有数据改变,信号内部接收到数据,就会马上发出数据。

2. 事件类型:

next:发送数据到下一个管道

error:发送数据失败

completed:发送数据完成

注意:

信号类(RACSiganl),只是表示当数据改变时,信号内部会发出数据,它本身不具备发送信号的能力,而是交给内部一个订阅者去发出。

默认一个信号都是冷信号,也就是值改变了,也不会触发,只有订阅了这个信号,这个信号才会变为热信号,值改变了才会触发。

如何订阅信号:调用信号RACSignal的subscribeNext就能订阅。

```

    //  创建信号

    RACSignal *signal1 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        // 发送信号

        [subscriber sendNext:@"发送信号"];

        [subscriber sendCompleted];

        return [RACDisposable disposableWithBlock:^{

            // 信号什么时候被取消:1.自动取消,当一个信号的订阅者被销毁的时候,就会自动取消订阅 2.主动取消

            // block调用时刻:一旦一个信号,被取消订阅的时候就会调用

            // block作用:当信号取消订阅,用于清空一些资源

            NSLog(@"信号被取消订阅");

        }];

    }];

  //  订阅信号

   RACDisposable *disposable =  [signal1 subscribeNext:^(id x) {

        NSString *text = x;

        NSLog(@"得到订阅值:%@",text);

    } completed:^{

        NSLog(@"******完成******");

    }];

  // 取消订阅(主动取消)

    [disposable dispose];

```

3. 过滤 — Filter

说明:过滤信号,使用它可以获取满足条件的信号,举个形象的比喻就是一张可以自由设置网口大小的渔网,根据自己需要,对网口进行设置就可以捕到特定规格的鱼。

用法:在用户登录时,我们需要关心用户名长度是否符合要求,比如要求字符长度超过10才可以往下面执行

```

  [[self.textTF.rac_textSignal filter:^BOOL(NSString *value) {

               return value.length > ;

    }] subscribeNext:^(id x) {

        NSLog(@"过滤后的值:%@",x);

    }];

```

4. 映射 — Map :把源信号内容映射成新的内容,简单点说就是将数据改成自己想要的数据。

map操作通过block改变了事件的数据。map从上一个next事件接收数据,通过执行block把返回值传给下一个next事件。(map 可以返回任何oc对象)在上面的代码中,map以NSString为输入,取字符串的长度,返回一个NSNumber。

注: 能看到map操作之后的步骤收到的都是NSNumber实例。你可以使用map操作来把接收的数据转换成想要的类型,只要它是个对象。

RACSignal *usernameLengthSignal =

[[self.usernameTextField.rac_textSignal map:^id(NSString *value) {

return @(value.length);

}];

5. 状态推导 — RAC()

说明:用于给某个对象的某个属性绑定。

用法:比如只要文本框文字改变,就会修改label的文字

RAC(self.labelView,text) = _textField.rac_textSignal;

6. 聚合信号

说明:聚合任意数量的信号,然后生成一个新的信号

用法:比如登录按钮只有当用户名和密码输入框的输入都有效时才能进行点击

7.  map —> flattenMap : 用于把源信号内容映射成新的内容。

flattenMap:

   // 监听文本框的内容改变,把结构重新映射成一个新值.

  // flattenMap作用:把源信号的内容映射成一个新的信号,信号可以是任意类型。

    // flattenMap使用步骤:
// 1.传入一个block,block类型是返回值RACStream,参数value
// 2.参数value就是源信号的内容,拿到源信号的内容做处理
// 3.包装成RACReturnSignal信号,返回出去。 // flattenMap底层实现:
// 0.flattenMap内部调用bind方法实现的,flattenMap中block的返回值,会作为bind中bindBlock的返回值。
// 1.当订阅绑定信号,就会生成bindBlock。
// 2.当源信号发送内容,就会调用bindBlock(value, *stop)
// 3.调用bindBlock,内部就会调用flattenMap的block,flattenMap的block作用:就是把处理好的数据包装成信号。
// 4.返回的信号最终会作为bindBlock中的返回信号,当做bindBlock的返回信号。
// 5.订阅bindBlock的返回信号,就会拿到绑定信号的订阅者,把处理完成的信号内容发送出来。 [[_textField.rac_textSignal flattenMap:^RACStream *(id value) { // block什么时候 : 源信号发出的时候,就会调用这个block。 // block作用 : 改变源信号的内容。 // 返回值:绑定信号的内容.
return [RACReturnSignal return:[NSString stringWithFormat:@"输出:%@",value]]; }] subscribeNext:^(id x) { // 订阅绑定信号,每当源信号发送内容,做完处理,就会调用这个block。 NSLog(@"%@",x); }];

map:

 // 监听文本框的内容改变,把结构重新映射成一个新值.

    // Map作用:把源信号的值映射成一个新的值

    // Map使用步骤:
// 1.传入一个block,类型是返回对象,参数是value
// 2.value就是源信号的内容,直接拿到源信号的内容做处理
// 3.把处理好的内容,直接返回就好了,不用包装成信号,返回的值,就是映射的值。 // Map底层实现:
// 0.Map底层其实是调用flatternMap,Map中block中的返回的值会作为flatternMap中block中的值。
// 1.当订阅绑定信号,就会生成bindBlock。
// 3.当源信号发送内容,就会调用bindBlock(value, *stop)
// 4.调用bindBlock,内部就会调用flattenMap的block
// 5.flattenMap的block内部会调用Map中的block,把Map中的block返回的内容包装成返回的信号。
// 5.返回的信号最终会作为bindBlock中的返回信号,当做bindBlock的返回信号。
// 6.订阅bindBlock的返回信号,就会拿到绑定信号的订阅者,把处理完成的信号内容发送出来。 [[_textField.rac_textSignal map:^id(id value) {
// 当源信号发出,就会调用这个block,修改源信号的内容
// 返回值:就是处理完源信号的内容。
return [NSString stringWithFormat:@"输出:%@",value];
}] subscribeNext:^(id x) { NSLog(@"%@",x);
}];

FlatternMap和Map的区别:

FlatternMap中的Block返回信号。

Map中的Block返回对象。

开发中,如果信号发出的值不是信号,映射一般使用Map

开发中,如果信号发出的值是信号,映射一般使用FlatternMap

    // 创建信号中的信号
RACSubject *signalOfsignals = [RACSubject subject];
RACSubject *signal = [RACSubject subject]; [[signalOfsignals flattenMap:^RACStream *(id value) { // 当signalOfsignals的signals发出信号才会调用
NSLog(@"3. ***");
return value; }] subscribeNext:^(id x) { // 只有signalOfsignals的signal发出信号才会调用,因为内部订阅了bindBlock中返回的信号,也就是flattenMap返回的信号。
// 也就是flattenMap返回的信号发出内容,才会调用。 NSLog(@"%@4. 最后输出",x);
}]; // 信号的信号发送信号
[signalOfsignals sendNext:signal]; // 信号发送内容
[signal sendNext:@]; // signal 发送内容 才会激活这个signal signalOfsignals 发送信号才会激活这个信号 然后走到flattenMap这个里面 现在订阅这这信号但是不会触发 只有falttenMap 返回信号后才会触发这个信号 最后输出 最后 signal 发送信号 激活了 signal 由于 signalOfsignal 发送了signal 当sinal被激活后 signalOfsignal也激活了信号 然后往下面一步步执行...

8. 添加附加操作(doNext:)

说明:执行Next之前,会先执行这个Block,简单说就是在一段逻辑执行前进行拦截,然后先执行一段特别操作,再操作接下来的逻辑

- (RACSignal *)doNext:(void (^)(id x))block

用法:还是拿登录的场景来说,当登录service正在校验用户名和密码时,登录按钮应该是不可点击的。这会防止用户多次执行登录操作。还有,如果登录失败了,用户再次尝试登录时,应该隐藏错误信息。

ReactiveCocoa学习总结(2)的更多相关文章

  1. ReactiveCocoa学习资料

    ReactiveCocoa 学习资料: ReactiveCocoa入门教程:第一部分 http://www.cocoachina.com/ios/20150123/10994.html Reactiv ...

  2. ReactiveCocoa 学习资料

    之前就有听说,感觉很强大,ReactiveCocoa更加被Mattt Thompson大神称为开启一个新Objective-C纪元.所以觉得非常有学习的必要了. 一些很好的学习资料: Reactive ...

  3. ReactiveCocoa学习总结

    最近一直断断续续学习关于ReactiveCocoa的知识内容,对于它的一些基础内容将通过本文进行一个总结,主要是一些入门知识 一:RACSignal一些运用 @interface RACSignalT ...

  4. iOS开发ReactiveCocoa学习笔记(六)

    RAC操作方法三. demo地址:https://github.com/SummerHH/ReactiveCocoa.git doNext deliverOn timeout interval del ...

  5. iOS开发ReactiveCocoa学习笔记(一)

    学习 RAC 我们首先要了解 RAC 都有哪些类 RACSignal RACSubject RACSequence RACMulticastConnection RACCommand 在学习的时候写了 ...

  6. ReactiveCocoa学习

    ReactiveCocoa常见类 6.1RACSiganl:信号类,一般表示将来有数据传递,只要有数据改变,信号内部接收到数据,就会马上发出数据. 注意: 信号类(RACSiganl),只是表示当数据 ...

  7. CocoaPods ReactiveCocoa 学习实践一 之 配置环境

    1.安装CocoaPods 1.00.参考 CocoaPods 文档 1.01.是否已安装 which pod 1.1.升级gem命令 sudo gem update --system 1.2.切换C ...

  8. ReactiveCocoa学习总结(1)

    1. 它是什么? 官方解释: [RACSignal] is a push-driven stream with a focus on asynchronous event delivery throu ...

  9. iOS开发ReactiveCocoa学习笔记(五)

    ReactiveCocoa常见操作方法介绍: demo地址:https://github.com/SummerHH/ReactiveCocoa.git filter ignore ignoreValu ...

  10. iOS开发ReactiveCocoa学习笔记(四)

    ReactiveCocoa常见操作方法介绍: demo地址:https://github.com/SummerHH/ReactiveCocoa.git 1.1 ReactiveCocoa操作须知 所有 ...

随机推荐

  1. Python学习笔记之基本语法学习1

    ★学习目标: 用Python做HTTP接口测试 ★学习的大纲: ●Python语言基础(安装,第一个案例,基本语法等) ●Request模块使用 ●编写一个简单功能的接口测试案例 ●HTTP协议基础 ...

  2. deepin系统如何安装deb格式的软件

    很简单,命令如下: sudo dpkg -i *.deb 记得路径要对

  3. 批量安装python库函数---pip

    废话少说,要的就是干货 pip install -r 文件名 注意如果输入文件名报错,建议使用文件的绝对路径. 作者:marsggbo

  4. Spring+SpringMVC+MyBatis+easyUI整合优化篇(二)Log4j讲解与整合

    日常啰嗦 上一篇文章主要讲述了一下syso和Log间的一些区别与比较,重点是在项目的日志功能上,因此,承接前文<Spring+SpringMVC+MyBatis+easyUI整合优化篇(一)Sy ...

  5. Sass实战 sass官网

    Sass实战 sass官网 1.相关视频教程:http://pan.baidu.com/s/1eSl8bUa 1.1我的项目源码:http://pan.baidu.com/s/1dFmqbyp 1.2 ...

  6. Tcl与Design Compiler (十二)——综合后处理

    本文如果有错,欢迎留言更正:此外,转载请标明出处 http://www.cnblogs.com/IClearner/  ,作者:IC_learner 概述 前面也讲了一些综合后的需要进行的一些工作,这 ...

  7. js的搜索遍历精讲

    搜索算法应该算是每种算法的重点与难点了,本文将讲解JavaScript中的各种常用的遍历算法:希望对大家有所帮助. 深度优先遍历顺序:1245367      广度优先遍历:1234567 1.深度优 ...

  8. Combination Sum系列问题

    主要使用方法是backtracking. Combination Sum Given a set of candidate numbers (C) and a target number (T), f ...

  9. 解决eclipse中文字很小

    新下载的eclipse4.2.1版本,显示中文字体很小,但是英文比较正常.网上查看要更改字体大小,但是更改后英文也变大了,不是想要的结果. window – preferences – general ...

  10. 1136: 零起点学算法43——多组测试数据输出I

    1136: 零起点学算法43--多组测试数据输出I Time Limit: 1 Sec  Memory Limit: 128 MB   64bit IO Format: %lldSubmitted: ...