ReactiveCocoa学习之一

ReactiveCocoa学习之一

1、ReactiveCocoa常见类

1.1、RACSiganl

RACSiganl信号类,一般表示将来有数据传递,只要有数据改变,信号内部接受到数据,就会马上发出数据。
<pre>
第一步:[RACSignal createSignal]来获得signal
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//part 3: 进入didSubscribe,通过[subscriber sendNext:]来执行next block
[subscriber sendNext:@1];
NSLog(@"hehe");
//如果不在发送数据,最好发送信号完成
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
NSLog(@"信号被销毁");
}];
}];
// 第二步 订阅信号,才会激活信号.
[signal subscribeNext:^(id x) {
NSLog(@"S1:-->%@",x);
}];

</pre>
<ol>
<li>[RACSignal createSignal:<#^RACDisposable *(id<RACSubscriber> subscriber)didSubscribe#>];来获得signal。调用子类RACDynamicSignal的createSignal来返回一个signal,并在signal中保存后面的 didSubscribe这个block
<li>[signal subscribeNext]先会获得一个subscriber,这个subscriber中保存了nextBlock、errorBlock、completedBlock
由于这个signal其实是RACDynamicSignal类型的,这个[self subscribe]方法会调用步骤一中保存的didSubscribe,参数就是1中的subscriber
<li>siganl的didSubscribe中调用[subscriber sendNext:@1];
sendNext底层其实就是执行subscriber的nextBlock
</ol>
<ol>
<li>RACSubscriber
<pre>@protocol RACSubscriber <NSObject></pre>
是一个协议。只要遵守这个协议,并且实现方法才能成为订阅者。通过create创建的信号,都有一个订阅者,帮助他发送数据。
<li>RACDisposable 用于取消订阅或者清理资源,当信号发送完成或者发送错误的时候,就会自动触发它。
</ol>

1.2 RACSubject

RACSubject:热信号 热信号就是在管线创建之后,不管是否有配套的工人,管线都会开始运作,可以随时根据外部条件送出数据。送出数据时,如果管线上有工人,数据被工人加工处理,如果没有工人,数据将被抛弃。 此时由于还没有订阅者,如果代码写在这里的话,数据会被抛弃。
<pre>
//创建信号
RACSubject *subject = [RACSubject subject];
//发送信号 1⃣️
[subject sendNext:@"hha"];
//订阅信号,
[subject subscribeNext:^(id x) {
NSLog(@"第一个订阅者%@",x);
}];
[subject subscribeNext:^(id x) {
NSLog(@"第二个订阅者%@",x);
}];
//发送信号 2⃣️
[subject sendNext:@"hhwrwee"];

//[subject sendNext:@"hhwrwee"]; 会调用一下方法

  • (void)sendNext:(id)value {
    [self enumerateSubscribersUsingBlock:^(id<RACSubscriber> subscriber) {
    [subscriber sendNext:value];//(1)
    }];
    }
    </pre>

其中:1⃣️中发送的信号没有被订阅者接收到,因为发送信号之前没有订阅者。这个数据将被抛弃

2⃣️发送的信号会被 两个订阅者都接收到。

当subject调用sendNext方法是。RACSubject就会遍历一遍自己的subcribers数组,并调用各数组元素(subscriber)准备好的sendNextBlock (1)
在调用subscribeNext时热信号RACSubject仅仅只是将subscriber加入到订阅者数组中,其它啥事不干。
3⃣️由于RACSubject是先有订阅者,在发送信息给订阅者接受,可以实现代理回调

1.3 RACReplaySubject

RACReplaySubject是RACSubject的一个子类。如果一个信号每被订阅一次,就需要把之前的值重复发送一遍,使用重复提供信号类。可以设置capacity数量来限制缓存的value的数量,即只缓充最新的几个值。
<pre>
RACReplaySubject *replaySub = [RACReplaySubject subject];
[replaySub sendNext:@1];
[replaySub sendNext:@2];
[replaySub subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
[replaySub subscribeNext:^(id x) {
NSLog(@"%@",x);
}];

ReactiveCocoa[1982:128524] 1
ReactiveCocoa[1982:128524] 2
ReactiveCocoa[1982:128524] 1
ReactiveCocoa[1982:128524] 2


  • (void)sendNext:(id)value {
    @synchronized (self) {
    [self.valuesReceived addObject:value ?: RACTupleNil.tupleNil];
    [super sendNext:value];
    if (self.capacity != RACReplaySubjectUnlimitedCapacity && self.valuesReceived.count > self.capacity) {
    [self.valuesReceived removeObjectsInRange:NSMakeRange(0, self.valuesReceived.count - self.capacity)];}}}
    </pre>

其中:1⃣️sendNext方法时,现将value保存下来

2⃣️subscribeNext,遍历订阅者发送保存下来的所有值。

1.4 RACTuple和RACSequence

RACTuple(A tuple is an ordered collection of objects)是一个有序集合。RACSequence(Represents an immutable sequence of values)values的一个队列。
<pre>
NSArray *number = @[@1,@2,@3,@4];
//遍历数组
//1、RACSequence = number.rac_sequence得到有值得队列
//2、RACSequence转换RACSignal信号类,numbers.rac_sequence.signal
//订阅信号。遍历数组
[number.rac_sequence.signal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];

另外:
//得到队列中的第一个值
[number.rac_sequence head]
//得到一个队列的枚举器
[number.rac_sequence objectEnumerator]
//元组
NSDictionary *dict = @{@"name":@"xmg",@"age":@18};
[dict.rac_sequence.signal subscribeNext:^(id x) {
//元组解包 x是一个键值对 键值对解包可用于model赋值
RACTupleUnpack(NSString *key,NSString *value) = x;
NSLog(@"%@,%@",key,value);
}];

</pre>

1.5 RACCommand

A command is a signal triggered in response to some actionRAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,他可以很方便的监控事件的执行过程。
<pre>
//1.创建命令 initWithSignalBlock:(RACSignal * (^)(id input))signalBlock
//2.在signalBlock中,创建RACSignal,并且作为signalBlock的返回值
//3.执行命令 - (RACSignal *)execute:(id)input
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
return [NetWorkingModel networkingWithParams:nil url:@"https://www.baidu.com"];
}];
self.command = command;
[command.executionSignals subscribeNext:^(RACSignal *name) {
[name subscribeNext:^(id x) {
NSLog(@"%@",x); //这里
}];
}];
//执行命令 不过没有这行代码command不能执行
[self.command execute:nil];

</pre>
//网络请求的一个类
<pre>
+(RACSignal *)networkingWithParams:(id)params url:(NSString *)url{
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
[manager setResponseSerializer:[AFHTTPResponseSerializer serializer]];
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"GET" URLString:url parameters:params error:nil];
NSURLSessionTask *task = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
NSString *dataString =[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
[subscriber sendNext:dataString];
[subscriber sendCompleted];
}];
[task resume];
return [RACDisposable disposableWithBlock:^{
NSLog(@"清号被销毁");
}];
}];
return signal;
}</pre>

1.6RACMulticastConnection

A multicast connection encapsulates the idea of sharing one subscription to a signal to many subscribers.利用热信号可以有多个订阅者,是一对多,信号可以与订阅者共享信息。来限制重复订阅
<pre>
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//发送信号
NSLog(@"%d",++i);
[subscriber sendNext:@(i)];
NSLog(@"hehe");
//如果不在发送数据,最好发送信号完成
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
NSLog(@"信号被销毁");
}];
}];
RACMulticastConnection *connect = [signal publish];
//订阅一信号和订阅二信号接受到的信息是一样的
[connect.signal subscribeNext:^(id x) {
NSLog(@"%@--->订阅一信号",x);
}];
[connect.signal subscribeNext:^(id x) {
NSLog(@"%@---->订阅二信号",x);
}];
[connect connect];
</pre>
<pre>
/- (RACMulticastConnection *)publish {
RACSubject *subject = [[RACSubject subject] setNameWithFormat:@"[%@] -publish", self.name];
RACMulticastConnection *connection = [self multicast:subject];
return connection;
}
</pre>
<pre>
/- (RACDisposable *)connect {
BOOL shouldConnect = OSAtomicCompareAndSwap32Barrier(0, 1, &_hasConnected);
if (shouldConnect) {self.serialDisposable.disposable = [self.sourceSignal subscribe:_signal];
}
return self.serialDisposable;
}
</pre>
其中[signal publish]可知这里生成了一个RACSubject热信号。connect.sourceSignal -> RACSignal(原始信号) connect.signal -> RACSubject。后面操作的都是RACSubject信号

[connect connect];连接之后可知原始信号被RACSubject订阅了。就是subscriber
subscribeNext:方法的调用实际上是RACSubject调用起subscribeNext。
subscriber会向所有订阅者发送信号。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容

  • 前言 之前对RAC有了一个基本的认识,了解了它的作用,以及RAC的运行机制,我们知道只要是信号(RACSignal...
    大大盆子阅读 4,498评论 0 11
  • 1.ReactiveCocoa常见操作方法介绍1.1 ReactiveCocoa操作须知所有的信号(RACSign...
    IIronMan阅读 2,594评论 2 17
  • 前言由于时间的问题,暂且只更新这么多了,后续还会持续更新本文《最快让你上手ReactiveCocoa之进阶篇》,目...
    Karos_凯阅读 1,738评论 0 6
  • RAC使用测试Demo下载:github.com/FuWees/WPRACTestDemo 1.ReactiveC...
    FuWees阅读 6,368评论 3 10
  • 诗歌:铜钱草 人皆醉的时候没有人独醒 叮咚的铁币铜币银币金币 有人会装模作样却人人少不了这币的魅力 钱迷的眼里都是...
    浅木sun阅读 595评论 2 5