美文网首页
ReactiveCocoa学习之一

ReactiveCocoa学习之一

作者: 低吟浅唱1990 | 来源:发表于2016-07-03 17:22 被阅读54次

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会向所有订阅者发送信号。

相关文章

  • ReactiveCocoa学习之一

    ReactiveCocoa学习之一 1、ReactiveCocoa常见类 1.1、RACSiganl RACSig...

  • ReactiveCocoa学习

    前言 前段时间学习ReactiveCocoa基础,总结出来一些常用的方法,希望对学习ReactiveCocoa人有...

  • ReactiveCocoa 学习之路之史上最全攻略

    ReactiveCocoa 学习之路之史上最全攻略 本文介绍的是史上最牛叉的ios开发新框架之一,最大的特点就是:...

  • ReactiveCocoa v2.5 源码解析之架构总览

    ReactiveCocoa学习系列总结 1.ReactiveCocoa v2.5 源码解析之架构总览2.RAC 中...

  • ReactiveCocoa学习

    ReactiveCocoa学习地址:https://www.jianshu.com/p/8dbe8878d1c5?...

  • ReactiveCocoa学习

    http://www.jianshu.com/p/e10e5ca413b7http://www.jianshu.c...

  • ReactiveCocoa 学习

    参考:袁峥Seemygo最快让你上手ReactiveCocoa之基础篇最快让你上手ReactiveCocoa之进阶篇

  • ReactiveCocoa学习

    ReactiveCocoa我觉得写的好的文章: http://benbeng.leanote.com/post/R...

  • ReactiveCocoa 学习

    1、热信号 冷信号 细说ReactiveCocoa的冷信号与热信号(一) - 美团技术团队 细说ReactiveC...

  • Reactivecocoa 学习

    作为一个iOS开发者,你写的每一行代码几乎都是在相应某个事件,例如按钮的点击,收到网络消息,属性的变化(通过KVO...

网友评论

      本文标题:ReactiveCocoa学习之一

      本文链接:https://www.haomeiwen.com/subject/puxcjttx.html