ReactiveCocoa common class

RACSignal: signal class; RACSubscriber is agreement

Introduction to the

The RACSignal class is used when data is generated

The default is cold signals and you must subscribe to the signals class

RACSignal usage steps

Create signal (cold signal is created by default)

DidSubscribe call: Called whenever a signal is subscribed

DidSubscribe: send data

SubscribeNext: Subscribes

NextBlock call: called as soon as the subscriber sends data

NextBlock is used to process data and display it on the UI

Send signal (sendNext:)

NextBlock is executed whenever the subscriber calls sendNext

As long as you subscribe to the Race DynamicSignal it will execute didSubscribe

The premise is RACDynamicSignal, different types of signal subscriptions, the processing of subscriptions is different

How to use RACSignal

1. CreateSignal + (RACSignal *)createSignal:(RACDisposable * (^)(id subscriber))didSubscribe

– (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock

3. Send signals – (void)sendNext:(id)value

RACSignal implementation:

1. Create a signal, first save didSubscribe to the signal, will not fire.

2. When signals are subscribed, signal’s subscribeNext:nextBlock is called

2.2 subscribeNext creates subscriber internally and stores nextBlock in subscriber.

2.1 SiganL’s didSubscribe will be called internally by subscribeNext

3. Call [subscriber sendNext:@1] in siganl didSubscribe;

3.1 The underlying level of sendNext is the nextBlock of subscriber execution

// 1. Create signal

RACSignal *siganl = [RACSignal createSignal:^RACDisposable *(id subscriber) {

// Block call time: Block is called whenever a subscriber subscribes to a signal.

// 2. Send signals

[subscriber sendNext:@1];

// If the data is not sent, it is better to send the signal to complete, internal will automatically call [RACDisposable disposable] unsubscribe signal.

[subscriber sendCompleted];

return [RACDisposable disposableWithBlock:^{

// Block call time: When the signal is completed or incorrectly sent, the block is automatically executed to unsubscribe the signal.

// After the Block is executed, the current signal is no longer subscribed.

NSLog(@” Signal destroyed “);

}];

}];

// 3. Subscribe to the signal to activate the signal.

[siganl subscribeNext:^(id x) {

// Block call time: Block is called whenever a signal sends data.

NSLog(@” received data :%@”,x);

}];

2. RACDisposable: Unsubscribe

Automatically unsubscribe as soon as the signal sends data

The subscriber will not automatically unsubscribe from the signal as long as the subscriber is present

Call [the disposable dispose]; Will be canceled

3. RACSubject: Signal provider, which can act as a signal itself or as a subscriber

You must subscribe before you send a signal

Usage scenario: It is usually used instead of an agent, so you do not need to define the agent

RACSubject usage steps

1. Create signal [RACSubject subject], unlike RACSiganl, create signal without block.

– (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock

3. Send sendNext (id)value

RACSubject: The underlying implementation is different from RACSignal.

1. Call the subscribeNext subscription signal, only saving the subscriber whose nextBlock has been assigned a value.

2. Call sendNext to send a signal and iterate over all the subscribers just saved, calling nextBlock of the subscribers one by one.

// 1. Create signal

RACSubject *subject = [RACSubject subject];

// 2. Subscribe signal

[subject subscribeNext:^(id x) {

// Block call time: when the signal issues a new value, it is called.

NSLog(@” first subscriber %@”,x);

}];

[subject subscribeNext:^(id x) {

// Block call time: when the signal issues a new value, it is called.

NSLog(@” second subscriber %@”,x);

}];

// 3. Send signals

[subject sendNext:@”1″];

4. RACReplaySubject: Repeat provide signal class, which is a subclass of RACSubject

RACReplaySubject can send signals first, while subscribing to signals, RACSubject cannot.

Usage scenario 1: If a signal is subscribed once, it needs to send the previous value 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.

RACReplaySubject

1. Create signal [RACSubject subject], unlike RACSiganl, create signal without block.

2. You can subscribe or send signals first.

2.1 subscribe – (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock

2.2 sending signals sendNext:(id)value

RACReplaySubject: The underlying implementation is different from RACSubject.

1. Call sendNext to send a signal, save the values, and iterate over all the subscribers you just saved, calling nextBlock for each subscriber one by one.

2. Call the subscribeNext subscription signal, iterate through all the saved values, and call the subscriber’s nextBlock one by one

If you want to repeat all the values before a signal is subscribed, you need to send the signal before the subscribed signal. That is, save the value first, before subscribing to the value.

// 1. Create signal

RACReplaySubject *replaySubject = [RACReplaySubject subject];

// 2. Send signals

[replaySubject sendNext:@1];

[replaySubject sendNext:@2];

// 3. Subscribe signal

[replaySubject subscribeNext:^(id x) {

NSLog(@” data received by the first subscriber %@”,x);

}];

// Subscribe signal

[replaySubject subscribeNext:^(id x) {

NSLog(@” data received by the second subscriber %@”,x);

}];

>>> RACSubject replaces the agent

Requirements:

1. Add a button to the current controller, modal to another controller interface

2. There is a button in the view of another controller. Click the button to notify the current controller

Step 1: On the second controller. H, add a RACSubject instead of the proxy.

@interface TwoViewController : UIViewController

@property (nonatomic, strong) RACSubject *delegateSignal;

@end

Step 2: Listen for the second controller button click

@implementation TwoViewController

– (IBAction)notice:(id)sender {

// Notify the first controller that the button has been clicked

// Notify the agent

// Check whether the proxy signal has a value

if (self.delegateSignal) {

// If it has a value, it needs to be notified

[self.delegateSignal sendNext:nil];

}

}

@end

Step 3: In the first controller, listen for the jump button, assign a value to the second controller’s proxy signal, and listen.

@implementation OneViewController

– (IBAction)btnClick:(id)sender {

Create a second controller

TwoViewController *twoVc = [[TwoViewController alloc] init];

// Set the proxy signal

twoVc.delegateSignal = [RACSubject subject];

// Subscribe to proxy signals

[twoVc.delegateSignal subscribeNext:^(id x) {

NSLog(@” hit the notification button “);

}];

// Jump to the second controller

[self presentViewController:twoVc animated:YES completion:nil];

}

@end

5. RACTuple: Tuple class

RACSequence: Collection class, used instead of NSArray and NSDictionary, to quickly iterate over groups and dictionaries

// 1

NSArray *numbers = @[@1,@2,@3,@4];

// There are three steps

RACSequence numbers.rac_sequence ()

// Add RACSequence to RACSignal,numbers. Rac_sequence

// Step 3: Subscribe signal, activate signal, automatically traverses all values in the set.

[numbers.rac_sequence.signal subscribeNext:^(id x) {

NSLog(@”%@”,x);

}];

// 2. Iterating through the dictionary, the resulting key-value pairs are wrapped as RACTuple(tuple object)

NSDictionary *dict = @{@”name”:@”HMJ”,@”age”:@18};

[dict.rac_sequence.signal subscribeNext:^(RACTuple *x) {

// Unpack the tuple, which assigns the values of the tuple to the variables in the argument in order

RACTupleUnpack(NSString *key, NSString *value) = x;

// It is equivalent to the following

//        NSString *key = x[0];

//        NSString *value = x[1];

NSLog(@”%@ %@”,key,value);

}];

3. Dictionary to model

3.1 OC writing

NSString *filePath = [[NSBundle mainBundle] pathForResource:@”flags.plist” ofType:nil];

NSArray *dictArr = [NSArray arrayWithContentsOfFile:filePath];

NSMutableArray *items = [NSMutableArray array];

for (NSDictionary *dict in dictArr) {

FlagItem *item = [FlagItem flagWithDict:dict];

[items addObject:item];

}

3.2 the RAC writing

NSString *filePath = [[NSBundle mainBundle] pathForResource:@”flags.plist” ofType:nil];

NSArray *dictArr = [NSArray arrayWithContentsOfFile:filePath];

NSMutableArray *flags = [NSMutableArray array];

_flags = flags;

// rac_sequence Note: Calling subscribeNext does not execute nextBlock immediately, but rather wait a while.

[dictArr.rac_sequence.signal subscribeNext:^(id x) {

// use RAC to traverse the dictionary, x: dictionary

FlagItem *item = [FlagItem flagWithDict:x];

[flags addObject:item];

}];

NSLog(@”%@”,  NSStringFromCGRect([UIScreen mainScreen].bounds));

3.3 RAC advanced notation:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@”flags.plist” ofType:nil];

NSArray *dictArr = [NSArray arrayWithContentsOfFile:filePath];

// map the original value to a new value

// array: convert collections to arrays

// Underlying implementation: When a signal is subscribed, the original values in the collection are iterated, mapped to new values, and stored in a new array.

NSArray *flags = [[dictArr.rac_sequence map:^id(id value) {

return [FlagItem flagWithDict:value];

}] array];