ReactiveCocoa- Getting started is really easy (part 1)

About RACSubject

RACSubject: signal provider, very special, can act as a signal itself and also send a signal.

Scenarios: Used when passing a value, calling back, or replacing a delegate. Here’s an example: the current controller clicks a button, pushes to another controller interface, and another controller clicks a button, returning to the first controller page and receiving a message from the second interface.

OneViewController

- (void)viewDidLoad { [super viewDidLoad]; /* // 1. Create signal [RACSubject subject], create signal without block. // 2. Subscribe - (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock // 3. SendNext :(ID)value // RACSubject: The underlying implementation is different from RACSignal. // 1. Call the subscribeNext signal, which simply saves the subscriber and assigns the nextBlock to the subscriber. // 2. Call sendNext to send a signal to iterate over all the subscribers just saved, calling nextBlock for each subscriber one by one. */ self.button.frame = CGRectMake(100, 100, 80, 30); [self.view addSubview:self.button]; }#pragma mark---lazy loading  
- (UIButton *)button {  
    if(! _button) { _button = [[UIButton alloc] init]; [_buttonsetBackgroundColor:[UIColor redColor]];  
        [_button setTitle:@"Go To" forState:UIControlStateNormal]; // use rac_signalForControlEvents, Handle button click event [[_button rac_signalForControlEvents: UIControlEventTouchUpInside] subscribeNext: ^ (id) x {TwoViewController *twoVC = [[TwoViewController alloc] init]; [twoVC. Subject subscribeNext:^(id x) {// here x is the signal NSLog(@) sent by sendNext"% @", x);  
                [self.button setTitle:x forState:UIControlStateNormal];  
            }];  
              
            [self.navigationController pushViewController:twoVC animated:YES];  
              
        }];  
    }  
    return _button;  
}  
Copy the code

TwoViewController

@property (nonatomic,strong) RACSubject *subject;

- (void)viewDidLoad {  
    [super viewDidLoad];  
   self.button.frame = CGRectMake(50, 100, 50, 30);  
    self.view.backgroundColor = [UIColor purpleColor];  
    [self.view addSubview:self.button];  
}  

#pragma mark---lazy loading  
- (UIButton *)button {  
    if(! _button) { _button = [[UIButton alloc] init]; [_buttonsetBackgroundColor:[UIColor grayColor]];  
        [_button setTitle:@"Two Go" forState:UIControlStateNormal]; [[_button rac_signalForControlEvents: UIControlEventTouchUpInside] subscribeNext: ^ (id) x {/ / 3. Send a signal, transmission of values, Delegate [self.subject sendNext:@"zm"];  
             [self.navigationController popViewControllerAnimated:YES];  
        }];  
    }  
    return _button;  
}  
Copy the code

Differences between RACSubject and RACReplaySubject:

A RACSubject must subscribe to signals before it can send signals, whereas a RACReplaySubject can send signals before it subscribs, providing signal classes repeatedly. Usage Scenario 1: If each time a signal is subscribed, the previous value needs to be sent again, using repetition to provide the signal class.

Scenario 2: You can set capacity to limit the number of cached values. That is, only the latest values can be cached.

About RACCommand

RACCommand: a class used in RAC to process events. It can be packaged into this class to monitor how events are handled and how data is transferred.

Scenario: Listen for button clicks, network requests

Matters needing attention:

1. SignalBlock cannot return nil, must return a signal or [RACSignal Empty]

2. In the RACCommand, if the data is completed, [subscriber sendCompleted] must be called, indicating that the execution is completed. Otherwise, the RACCommand is always in execution.

3. Note that RACCommand needs to be strongly referenced, otherwise the signal in RACCommand will not be received, and the signal in RACCommand is sent late.

RACCommand return source data execution method:

Execute signal of signals, meaning that the data sent by a signal is a signal, not a normal type.

2. Subscribe to executionSignals to get signals returned by RACCommand, and subscribe to signals returned by signalBlock to get emitted values.

3. Listen to whether the command is executing

Concrete implementation examples:

- (void)test1 {// RACCommand: handle events //1. Create RACCommand *command= [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {//block call, Execute is called // input as an argument to execute the command. // Cannot return an empty signalreturn [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {  
            [subscriber sendNext:@"Data generated by executing commands"];  
            returnnil; }]; }]; // Subscribe to the signal inside the command // ** Mode 1: subscribe to the signal returned by executing the command //2. Run RACSignal *signal =[commandexecute:@1]; // Signal subscribeNext:^(id x) {NSLog(@"% @",x); }]; // Signal of signals(); // Signal of signals(); Signal source, signalofsignals, [x subscribeNext:^(id x) {NSLog(@)"% @", x);  
        }];  
//        NSLog(@"% @", x); }]; // 2. Run the [commandexecute:@2]; // ** Mode 3 // switchToLatest Obtains the latest sent signals, which can only be used for signals within signals. [command.executionSignals.switchToLatest subscribeNext:^(id x) { NSLog(@"% @", x); }]; // 2. Run the [commandexecute:@3]; } /* RACCommand is usually used to indicate the execution of an Action, such as clicking a Button. It has a few important properties: executionSignals/errors/executing. 1, Execute signals is a signal of signals. If we subscribe directly, we will get a signal, not the value we want. 2, the errors. Unlike normal signal, RACCommand errors are not implemented through sendError, but are passed through the errors attribute. 3, executing executing means executingcommandWhether the command is being executed. */ // Is the listening event completed - (void)test2 {// Note: the current command internal send data completion, must actively send complete // 1. Create the command RACCommand *command= [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {// Block call: when the command is executed, the return value is not allowed to be nilreturn[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {// Send data [subscriber sendNext:@"Data generated by executing commands"]; // *** sendCompleted ** [subscriber sendCompleted];returnnil; }]; }]; // Listen to the event to complete [command. Executing subscribeNext:^(id x) {if([x boolValue] == YES) {// NSLog(@"Currently executing %@", x);  
        }else{// NSLog(@) is not executed"Execution completed/Not executed"); }}]; // 2. Run the [command execute:@1];  
      
}  
Copy the code
About RACMulticastConnection

RACMulticastConnection: This class is used when a signal is subscribed multiple times to ensure that the signal is created without the side effect of multiple calls to the block that created the signal.

Note: RACMulticastConnection is created using either the -publish or -muticast: methods of RACSignal.

Usage scenario: Solve the multiple calls problem – Suppose that a request is sent in a signal once for each subscription, which results in multiple requests.

Use steps:

+ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe 2. RACMulticastConnection *connect = [signal publish]; 3. Subscribe signal, note: subscribe signal is not the previous signal, but the connected signal. [connect.signal subscribeNext:nextBlock] 4. Connection [is] the connect connectCopy the code

Concrete implementation examples:

- (void)test{// With RACMulticastConnection, send only one, no matter how many subscribers there are and no matter how many subscriptions there are. // 1. Send the request, wrapped in a signal, no matter how many subscribers, RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {// Send NSLog(@)"Request sent."); // Send signal [subscriber sendNext:@"data"];  
        returnnil; }]; //2. Create a connection class 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. The connection. Only when connected will the signal source into a heat signal [connection connect]; }Copy the code

Today, I will write here. This article mainly writes down some common use classes and common use scenarios. The next part is ready to write down the use of operators. If you have any questions, please leave a message.