RAC APIの概要

29147 ワード

一、よくあるクラス
1、RACSiganl    。
    RACEmptySignal :   ,     RACSignal   +empty   ;
    RACReturnSignal :    ,     RACSignal   +return:   ;
    RACDynamicSignal :    ,     block -        ,      RACSignal   +createSignal:              ;
    RACErrorSignal :    ,     RACSignal   +error:   ;
    RACChannelTerminal :    ,   RACChannel      ,        。
2、RACSubscriber    
3、RACDisposable             ,                ,       。
    RACSerialDisposable :   disposable      ,       disposable   ,        disposable             ;
    RACKVOTrampoline :     KVO   ,          ;
    RACCompoundDisposable :        disposable   ,            disposable   
    RACScopedDisposable :    dealloc          -dispose   。
4、RACSubject      ,        ,      。
    RACGroupedSignal :    ,     RACSignal      ;
    RACBehaviorSubject :        ,     ,               ;
    RACReplaySubject :    ,       ,     ,            。
5、RACTuple    ,  NSArray,     .
6、RACSequence RAC     
7、RACCommand RAC         ,         ,          ,       ,                。
8、RACMulticastConnection        ,      ,         ,            block,     ,         。
9、RACScheduler RAC    , GCD   。
    RACImmediateScheduler :         ,                ;
    RACQueueScheduler :          ,    GCD              ;
    RACTargetQueueScheduler :    RACQueueScheduler ,          GCD     target               ;
    RACSubscriptionScheduler :             。

二、よくある使い方
rac_signalForSelector :     
rac_valuesAndChangesForKeyPath: KVO
rac_signalForControlEvents:    
rac_addObserverForName     
rac_textSignal:         
rac_liftSelector:withSignalsFromArray:Signals:    Signals(    ),   signal   sendNext   ,        selector     。

三、よくあるマクロ
RAC(TARGET, [KEYPATH, [NIL_VALUE]]):              
RACObserve(self, name) :           ,      。
@weakify(Obj) @strongify(Obj)
RACTuplePack :      RACTuple(   )
RACTupleUnpack: RACTuple(   )        
RACChannelTo            

四、常用操作方法
flattenMap map                。
concat             ,          ,        
then         ,        ,    then     。
merge             ,                
zipWith             ,                ,                 ,        next  。
combineLatest:         ,             ,       signal       sendNext,         。
reduce  :            ,               

filter:    ,              .
ignore:         .
distinctUntilChanged:                       ,       。
take:      N    
takeLast:   N    ,    ,         ,      ,          .
takeUntil:(RACSignal *):              
skip:(NSUInteger):      ,   。
switchToLatest:  signalOfSignals(     ),           ,  signalOfSignals ,  signalOfSignals       。

doNext:   Next  ,      Block
doCompleted:   sendCompleted  ,      Block
timeout:  ,              ,    。
interval   :          
delay     next。
retry   :    ,            block,    .
replay  :          ,      
throttle  :            ,      ,             ,                 。

五、UI-Category(常用要約)
1、rac_prepareForReuseSignal:       
  UI: MKAnnotationView、UICollectionReusableView、UITableViewCell、UITableViewHeaderFooterView

2、rac_buttonClickedSignal:        
  UI:UIActionSheet、UIAlertView

3、rac_command:button 、         
  UI:UIBarButtonItem、UIButton、UIRefreshControl

4、rac_signalForControlEvents: control event   
  UI:UIControl

5、rac_gestureSignal UIGestureRecognizer       
  UI:UIGestureRecognizer

6、rac_imageSelectedSignal        
  UI:UIImagePickerController

7、rac_textSignal
  UI:UITextField、UITextView

8、          API
    rac_channelForControlEvents: key: nilValue:
      UI:UIControl 
    rac_newDateChannelWithNilValue:
      UI:UIDatePicker
    rac_newSelectedSegmentIndexChannelWithNilValue:
      UI:UISegmentedControl
    rac_newValueChannelWithNilValue:
      UI:UISlider、UIStepper
    rac_newOnChannel
      UI:UISwitch
    rac_newTextChannel
      UI:UITextField

六、Foundation-Category(常用要約)
1、NSArray
    rac_sequence     
2、NSData
    rac_readContentsOfURL: options: scheduler:  oc      
3、NSDictionary
    rac_sequence    
    rac_keySequence key   
    rac_valueSequence value   
4、NSEnumerator
    rac_sequence    
5、NSFileHandle
    rac_readInBackground     
6、NSIndexSet
    rac_sequence    
7、NSInvocation
    rac_setArgument: atIndex:     
    rac_argumentAtIndex      
    rac_returnValue          
8、NSNotificationCenter
    rac_addObserverForName: object:    
9、NSObject
    rac_willDeallocSignal           
    rac_description debug 
    rac_observeKeyPath: options: observer: block:      
    rac_liftSelector: withSignals:      next   
    rac_signalForSelector:       
    rac_signalForSelector:(SEL)selector fromProtocol:    
9、NSOrderedSet
    rac_sequence    
10、NSSet
    rac_sequence    
11、NSString
    rac_keyPathComponents            
    rac_keyPathByDeletingLastKeyPathComponent          
    rac_keyPathByDeletingFirstKeyPathComponent         
    rac_sequence     (character)
    rac_readContentsOfURL: usedEncoding: scheduler:   OC     
12、NSURLConnection
    rac_sendAsynchronousRequest       
13、NSUserDefaults
    rac_channelTerminalForKey       ,    

七、付録の使用例
1.RACSignal
// 1.    
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
        // 3.    
        [subscriber sendNext:@"ws"];
        // 4.    ,         ,       RACDisposable
        //          :1.    ,                       ,2.    ,
        //block      :               
        //block  :               
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"    ");
        }];
    }];
    // 2.     
    //subscribeNext
    //  nextBlock        
    //                     
    RACDisposable *disposable = [signal subscribeNext:^(id x) {
        // block     :                block
        NSLog(@"======%@", x);
    }];
    //     
    [disposable dispose];
.  :
    .  :   
    .      :                     
    .              
    .    ,        ,         
.    :
    .    
    .    
.    :
    .        ,     ,  nextBlock        。
    .         [RACDynamicSignal createSignal:didSubscribe];
    .  RACDynamicSignal didSubscribe
    .    [subscriber sendNext:value];
    .      nextBlock  

2.RACSubject
代替エージェントでよく使用される
  • 注意:RACSubjectとRACReplaySubjectの違いRACSubjectは、信号を送信する前に信号を購読しなければならないが、RACReplaySubjectは、信号を送信してから購読することができる.
    3.RACSequence
    辞書や配列を巡回するのによく使われます
    NSString *path = [[NSBundle mainBundle] pathForResource:@"flags.plist" ofType:nil];
        NSArray *dictArr = [NSArray arrayWithContentsOfFile:path];
        [dictArr.rac_sequence.signal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        } error:^(NSError *error) {
            NSLog(@"===error===");
        } completed:^{
            NSLog(@"ok---  ");
        }];
    
          
    
    NSDictionary *dict = @{@"key":@1, @"key2":@2};
        [dict.rac_sequence.signal subscribeNext:^(id x) {
            NSLog(@"%@", x);
            NSString *key = x[0];
            NSString *value = x[1];
            // RACTupleUnpack :        
            // RACTupleUnpack     :            ,         
            //         ,          
            RACTupleUnpack(NSString *key, NSString *value) = x;
            NSLog(@"%@ %@", key, value);
        } error:^(NSError *error) {
            NSLog(@"===error");
        } completed:^{
            NSLog(@"-----ok---  ");
        }];
    

    4.RACMulticastConnection
    複数の購読者がいますが、私たちが1つの信号を送信したい場合はどうすればいいですか?このときRACMulticastConnectionで実現できます.コードの例は次のとおりです.
    //     ,       :                  ,      
     RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
            // didSubscribeblock           。
            //     ---  afn
            NSLog(@"     ");
            //     
            [subscriber sendNext:@"ws"];
            return nil;
        }];
        [signal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        [signal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        [signal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
    
    //       。   RACMulticastConnection,         ,       ,      。
    // 1.    ,        ,         ,       
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
            //     
            NSLog(@"     ");
            //     
            [subscriber sendNext:@"ws"];
            return nil;
        }];
        //2.      
        RACMulticastConnection *connection = [signal publish];
        [connection.signal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        [connection.signal subscribeNext:^(id x) {
             NSLog(@"%@", x);
        }];
        [connection.signal subscribeNext:^(id x) {
             NSLog(@"%@", x);
        }];
        //3.   。                
        [connection connect];
    

    5.RACCommand
  • RACCommand:RACでイベントを処理するために使用されるクラスは、イベントをどのように処理するか、イベントのデータをどのように伝達するか、このクラスにパッケージすることができます.彼はイベントの実行過程を簡単に監視することができます.例えば、イベントが実行されたかどうかを見ることができます.
  • 使用シーン:傍受ボタンクリック、ネットワーク要求
  • //     
    // RACCommand:     
        //         
        // 1.    
        RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
            //block  ,           
            NSLog(@"%@",input); // input            
            //           nil
            return [RACSignal createSignal:^RACDisposable *(id subscriber) {
                [subscriber sendNext:@"         "];
                return nil;
            }];
        }];
    
        //                ?
        //          
        // **    :             
    
        // 2.    
        RACSignal *signal =[command execute:@2]; //         replaySubject           
        //            
        [signal subscribeNext:^(id x) {
            NSLog(@"%@",x);
        }];
    
    //     
     // 1.    
        RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
            //block  ,           
            NSLog(@"%@",input); // input            
            //           nil
            return [RACSignal createSignal:^RACDisposable *(id subscriber) {
                [subscriber sendNext:@"         "];
                return nil;
            }];
        }];
    
        //    :
        //     
        //   :              
        // executionSignals:   ,     ,signalofsignals:  ,        
        [command.executionSignals subscribeNext:^(RACSignal *x) {
            [x subscribeNext:^(id x) {
                NSLog(@"%@", x);
            }];
    //        NSLog(@"%@", x);
        }];
    
        // 2.    
        [command execute:@2];
    
    //     
    // 1.    
        RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
            // block  :           
            NSLog(@"%@", input);
            //           nil
            return [RACSignal createSignal:^RACDisposable *(id subscriber) {
                [subscriber sendNext:@"    "];
                return nil;
            }];
        }];
    
        //    
        // switchToLatest         ,         。
        [command.executionSignals.switchToLatest subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        // 2.    
        [command execute:@3];
    
    // switchToLatest--       
    //        
        RACSubject *signalofsignals = [RACSubject subject];
        RACSubject *signalA = [RACSubject subject];
         //     
    //    [signalofsignals subscribeNext:^(RACSignal *x) {
    //        [x subscribeNext:^(id x) {
    //            NSLog(@"%@", x);
    //        }];
    //    }];
        // switchToLatest:               
        [signalofsignals.switchToLatest subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        //     
        [signalofsignals sendNext:signalA];
        [signalA sendNext:@4];
    
    //          
     //  :            ,         
        // 1.    
        RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
            // block  :           
            NSLog(@"%@", input);
            //           nil
            return [RACSignal createSignal:^RACDisposable *(id subscriber) {
                //     
                [subscriber sendNext:@"         "];
    
                // ***      **
                [subscriber sendCompleted];
                return nil;
            }];
        }];
        //          
        [command.executing subscribeNext:^(id x) {
            if ([x boolValue] == YES) { //     
                NSLog(@"      %@", x);
            }else {
                //     /    
                NSLog(@"    /    ");
            }
        }];
    
        // 2.    
        [command execute:@1];
    

    6.RAC-コンビネーション
    //   ---                           。
    - (void)combineLatest {
    
        RACSignal *combinSignal = [RACSignal combineLatest:@[self.accountField.rac_textSignal, self.pwdField.rac_textSignal] reduce:^id(NSString *account, NSString *pwd){ //reduce        combineLatest        。
            // block:          ,    ,       。
            NSLog(@"%@ %@", account, pwd);
            return @(account.length && pwd.length);
        }];
    
        //    //     
        //    [combinSignal subscribeNext:^(id x) {
        //        self.loginBtn.enabled = [x boolValue];
        //    }];    // ----       ,     RAC 
        RAC(self.loginBtn, enabled) = combinSignal;
    }
    
    - (void)zipWith {
        //zipWith:            ,                ,                 ,        next  。
        //     A
        RACSubject *signalA = [RACSubject subject];
        //     B
        RACSubject *signalB = [RACSubject subject];
        //        
        // **-zipWith-**:             ,           UI
        //                  
        RACSignal *zipSignal = [signalA zipWith:signalB];
        [zipSignal subscribeNext:^(id x) {
            NSLog(@"%@", x); //            
        }];
    
        //          ,           ,        ,          [signalA zipWith:signalB]---  A  B
        [signalA sendNext:@1];
        [signalB sendNext:@2];
    
    }
    
    //                 
    // merge:           ,             
    - (void)merge {
        //     A
        RACSubject *signalA = [RACSubject subject];
        //     B
        RACSubject *signalB = [RACSubject subject];
        //    
        RACSignal *mergeSignal = [signalA merge:signalB];
        //     
        [mergeSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        //     ---               
        [signalB sendNext:@"   "];
        [signalA sendNext:@"   "];
    }
    
    // then ---     :      :                   ,        ,       
    - (void)then {
        //     A
        RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id subscriber) {
            //     
            NSLog(@"----       ---afn");
    
            [subscriber sendNext:@"     "];
            [subscriber sendCompleted]; //      sendCompleted  !
            return nil;
        }];
    
        //     B,
        RACSignal *signalsB = [RACSignal createSignal:^RACDisposable *(id subscriber) {
            //     
            NSLog(@"--       --afn");
            [subscriber sendNext:@"     "];
            return nil;
        }];
        //       
        // then;            
        RACSignal *thenSignal = [signalA then:^RACSignal *{
            //              
            return signalsB;
        }];
    
        //     
        [thenSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
    
    }
    
    // concat-----     :      :        ,           (     )
    - (void)concat {
        //   
    
        //     A
        RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id subscriber) {
            //     
            //        NSLog(@"----       ---afn");
    
            [subscriber sendNext:@"     "];
            [subscriber sendCompleted]; //      sendCompleted  !
            return nil;
        }];
    
        //     B,
        RACSignal *signalsB = [RACSignal createSignal:^RACDisposable *(id subscriber) {
            //     
            //        NSLog(@"--       --afn");
            [subscriber sendNext:@"     "];
            return nil;
        }];
    
    
        // concat:      
        //**-  -**:concat,          sendCompleted
        //       
        RACSignal *concatSignal = [signalA concat:signalsB];
        //       
        [concatSignal subscribeNext:^(id x) {
            NSLog(@"%@",x);
        }];
    
    }
    

    7.RAC-共通マクロ
     // RAC:                ,      ,                
        //  label text             
        RAC(self.label, text) = self.textField.rac_textSignal;
    //    [self.textField.rac_textSignal subscribeNext:^(id x) {
    //        self.label.text = x;
    //    }];
    
    /**
     *  KVO
     *  RACObserveL:                
     *          ,            
     */
     [RACObserve(self.view, center) subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
    
    //  textField       label,  label    ,
        RAC(self.label, text) = self.textField.rac_textSignal;
        [RACObserve(self.label, text) subscribeNext:^(id x) {
            NSLog(@"====label     ");
        }];
    
    /**
     *        
     */
     @weakify(self)
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
            @strongify(self)
            NSLog(@"%@",self.view);
            return nil;
        }];
        _signal = signal;
       @weakify(self) @strongify(self)       
    
    /**
     *   
     *         
     *               ,      
     */
     RACTuple *tuple = RACTuplePack(@1,@2,@4);
        //                  ,          。
        RACTupleUnpack_(NSNumber *num1, NSNumber *num2, NSNumber * num3) = tuple;// 4.  
        //         
        //               ,      
        NSLog(@"%@ %@ %@", num1, num2, num3);
    

    8.RAC-ろ過
    //    :   ,skip  2        
    //     :                       ,       ,    skip
     RACSubject *subject = [RACSubject subject];
        [[subject skip:2] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        [subject sendNext:@1];
        [subject sendNext:@2];
        [subject sendNext:@3];
    
    //distinctUntilChanged:--               ,       
        RACSubject *subject = [RACSubject subject];
        [[subject distinctUntilChanged] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        //     
        [subject sendNext:@1];
        [subject sendNext:@2];
        [subject sendNext:@2]; //      
    
    // take:       ,       ---  take 2         
    RACSubject *subject = [RACSubject subject];
        [[subject take:2] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        //     
        [subject sendNext:@1];
        [subject sendNext:@2];
        [subject sendNext:@3];
    
    //takeLast: take     ,            ,  ,         
    //   :takeLast      sendCompleted,        ,            
    RACSubject *subject = [RACSubject subject];
        [[subject takeLast:2] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        //     
        [subject sendNext:@1];
        [subject sendNext:@2];
        [subject sendNext:@3];
        [subject sendCompleted];
    
    // takeUntil:--- takeUntil       ,            sendCompleted,             。
     RACSubject *subject = [RACSubject subject];
        RACSubject *subject2 = [RACSubject subject];
        [[subject takeUntil:subject2] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        //     
        [subject sendNext:@1];
        [subject sendNext:@2];
        [subject2 sendNext:@3];  // 1
    //    [subject2 sendCompleted]; //  2
        [subject sendNext:@4];
    
    // ignore:       
     //ignore:     
        //ignoreValues:        
        // 1.    
        RACSubject *subject = [RACSubject subject];
        // 2.     
        RACSignal *ignoreSignal = [subject ignore:@2]; // ignoreValues:        
        // 3.    
        [ignoreSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        // 4.    
        [subject sendNext:@2];
    
    //          ,      
    //              5,          
        [[self.textField.rac_textSignal filter:^BOOL(id value) {
            // value       
            return [value length] > 5;
            //           。               
        }] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
    

    9.RAC-マッピング
  • RACのマッピングは実際の開発で何の役に立つのでしょうか.例えば、サーバが返すデータをブロックしたり、特定のものをデータにつなぎ合わせたり、データを操作して戻り値を変更したりしたい場合、RACのマッピングを考慮することができます.インスタンスコードは以下の
  • です.
    - (void)map {
        //     
        RACSubject *subject = [RACSubject subject];
        //     
        RACSignal *bindSignal = [subject map:^id(id value) {
    
            //               
            return [NSString stringWithFormat:@"ws:%@", value]; //         “123”      ws:
        }];
        //       
        [bindSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        //     
        [subject sendNext:@"123"];
    
    - (void)flatMap {
        //     
        RACSubject *subject = [RACSubject subject];
        //     
        RACSignal *bindSignal = [subject flattenMap:^RACStream *(id value) {
            // block:             
            // value:           
            //                
            return [RACReturnSignal return:value];
    
        }];
    
        // flattenMap         ,         (  ,x    value  ,      value    x      )
        //     
        [bindSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
    
        //     
        [subject sendNext:@"123"];
    
    }
    
    - (void)flattenMap2 {
        // flattenMap           
        //     
        RACSubject *signalofSignals = [RACSubject subject];
        RACSubject *signal = [RACSubject subject];
    
        //     
        //  1
        //    [signalofSignals subscribeNext:^(id x) {
        //
        //        [x subscribeNext:^(id x) {
        //            NSLog(@"%@", x);
        //        }];
        //    }];
        //   2
        //    [signalofSignals.switchToLatest  ];
        //   3
        //   RACSignal *bignSignal = [signalofSignals flattenMap:^RACStream *(id value) {
        //
        //        //value:         
        //        return value;
        //    }];
        //    [bignSignal subscribeNext:^(id x) {
        //        NSLog(@"%@", x);
        //    }];
        //   4--------        
        [[signalofSignals flattenMap:^RACStream *(id value) {
            return value;
        }] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
    
        //     
        [signalofSignals sendNext:signal];
        [signal sendNext:@"123"];
    }
    

    10.RAC-bind
    // 1.    
        RACSubject *subject = [RACSubject subject];
        // 2.    
       RACSignal *bindSignal = [subject bind:^RACStreamBindBlock{
           // block    :            。      ,
            return ^RACSignal *(id value, BOOL *stop){
                //      block    ,           block。
                //      (subject)    ,    block
                // block  :       
                // value:        ,
                value = @3; //       value    ,           44  x   
                NSLog(@"         :%@", value);
                //    ,   nil,       --- empty  alloc init。
            return [RACReturnSignal return:value]; //           
            };
        }];
    
        // 3.      
        [bindSignal subscribeNext:^(id x) {
    
            NSLog(@"             :%@", x);
        }];
        // 4.    
        [subject sendNext:@"123"];
    

    bind(バインド)の使用思想はHookのと同じである--->APIをブロックしてデータを操作することができ、データの戻りに影響を与える.信号を送ると30行のblockに来ます.このblockではデータをいくつか操作することができ、35行で印刷されたvalueとバインド信号を購読するとvalueが変わります.