ReactiveCocoa初識(一)

6749 ワード

入社してしばらく経ちましたが、開発任務がなく、昼間はブログを見て自分のものを書いて、夜はワールドカップを見て、あまり爽やかではありません.最近ReactiveCocoaを勉強しています.プロジェクトはReactiveObjCに導入されています.
RACSignal   RACSignalはRACコアのクラスで、使用するときはまず信号を作成し、信号を購読し、信号を作成するblockの中で信号を送信します.
- (void)RACSignal
{
    //1  
    RACSignal * signal = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        
        //3  
        [subscriber sendNext:@" "];
        
        return [RACDisposable disposableWithBlock:^{
            NSLog(@" ");
        }];
//        return nil;
    }];
    
    //2  
    RACDisposable * disposable = [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //4  
    [disposable dispose];
}

RACSubject   RACSubjectはRACSignalから継承され、RACSubscriberプロトコルにも従います.だからRACSubjectは信号を購読することも、信号を送信することもできます.使い方も購読して送信します.RACReplaySubjectとは異なり、RACReplaySubjectは先に送信してから購読することができます.
- (void)RACSubject
{    
    //1  
    RACSubject * subject = [RACSubject subject];
    
    //2  
    [subject subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //3  
    [subject sendNext:@" "];
}

RACSequence
- (void)RACSequence
{
    // 
    
    NSArray * array = @[@"1",@"2",@"3",@"3",@"5"];
    [array.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    // 
    RACTuple * tuple = RACTuplePack(array);
    NSLog(@"%@",tuple[0]);
    NSLog(@"%@",[tuple first]);
    NSLog(@"%@",[tuple last]);
    
    NSDictionary * dict = @{@"key1":@"value1",@"key2":@"value2"};
    [dict.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
        RACTupleUnpack(NSString * key,NSString * value) = x;
        NSLog(@"%@  %@",key,value);
    }];
    
    //     
    NSArray * newArray1 = [[array.rac_sequence map:^id _Nullable(id  _Nullable value) {
        return @"0";
    }] array];
    NSLog(@"%@",newArray1);
    
    //     
    NSArray * newArray2 = [[array.rac_sequence mapReplace:@"1"] array];
    NSLog(@"%@",newArray2);
}

RACMulticastConnection例えば、1つのネットワーク要求の結果を信号に設定し、複数のUIがこの信号を購読し、購読するたびに1回ネットワーク要求を行う.
RACSignal * signal = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        /* */
        [subscriber sendNext:@" "];
        return nil;
    }];
    
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];

これを回避するために、RACMulticastConnectionを使用してリンククラスを作成し、サブスクライバを接続し、信号源をホット信号にします.
- (void)RACMulticastConnection
{
    //   
    RACSignal * signal = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        [subscriber sendNext:@" "];
        return nil;
    }];
    
    // 
    RACMulticastConnection * connection = [signal publish];
    
    [connection.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    [connection.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    [connection.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //   
    [connection connect];
}

merge
- (void)merge
{
    RACSubject * subject1 = [RACSubject subject];
    RACSubject * subject2 = [RACSubject subject];
    RACSubject * subject3 = [RACSubject subject];
    
    [[RACSignal merge:@[subject1,subject2,subject3]] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    [subject1 sendNext:@"subject1"];
    [subject2 sendNext:@"subject2"];
    [subject3 sendNext:@"subject3"];
}

グループは、複数のタスクを完了してからメソッドを実行するGCDのようなタスクグループです.
- (void)group
{
    RACSignal * signalA = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        /* 1*/
        [subscriber sendNext:@" 1 "];
        return nil;
    }];
    
    RACSignal * signalB = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        /* 2*/
        [subscriber sendNext:@" 2 "];
        return nil;
    }];
    
    [self rac_liftSelector:@selector(dependSignalA:WithSignalB:) withSignalsFromArray:@[signalA,signalB]];
}

- (void)dependSignalA:(NSString *)str1 WithSignalB:(NSString *)str2
{
    
}

Notification&&KVO
- (void)Notification
{
    // removeObserver
    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"NotificationName" object:nil] subscribeNext:^(NSNotification * _Nullable x) {
        NSLog(@"%@",x);
    }];
}

- (void)KVO
{
    [[self.view rac_valuesForKeyPath:@"color" observer:self] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
}

Timer
- (void)Timer
{
    RACDisposable * disposable = [[RACSignal interval:1.f onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDate * _Nullable x) {
        // 
        NSLog(@"%@",x);
        
        [disposable dispose];
    }];
}

UI
- (void)UI
{
    UITextField * tf = [UITextField new];
    UITextField * tf2 = [UITextField new];
    UIButton * btn = [UIButton new];
    
    [[tf rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //filter   ignore
    [[[tf2.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
        return value.length > 6;
    }] ignore:@"666"] subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    // 
    [[btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    // 3   
    RAC(btn,enabled) = [RACSignal combineLatest:@[tf.rac_textSignal,tf2.rac_textSignal] reduce:^id (NSString * str1, NSString * str2){
        return @(str1.length > 3 && str2.length > 3);
    }];
}

IX ReactiveCocoaは応答型プログラミングフレームワークであり、iOSでは類似のコードに触れたことがない.しかし、前にAngularJSに接触したことがあり、中のng-model指令、一方向バインド、双方向バインドについて一定の理解を持っています.次はRACCommandを重点的に理解し、ログインしたDemoと組み合わせて実践します.    コード:ReactiveObjCDemo