美文网首页
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学习之一

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