RAC < 5 > circular reference analysis

RAC can take over all the events in iOS development, as mentioned in the previous article. Although the cost of learning is relatively large, without RAC, many events are not written in the same way. Write one thing in the East and one thing in the West.

How does RAC replace KVO?

@property (nonatomic,strong)Person *person;

- (void)viewDidLoad {

    [super viewDidLoad];

    

    //How RAC replaces KVO

    self.person = [[Person alloc] init];

    //Listen to the change of name attribute. Two parameters: who is the first listening object and the second listening attribute

    RACObserve(self.person, name);     //One line of code completes the KVO monitoring, and you don't need to cancel the monitoring by yourself. RAC has already helped you.

}

Use the previous section to see how it works:

- (void)viewDidLoad {

    [super viewDidLoad];

    self.person = [[Person alloc] init];

    ({ __attribute__((objc_ownership(weak))) id target_ = (self.person); [target_ rac_valuesForKeyPath:@(((void)(__objc_no && ((void)self.person.name, __objc_no)), "name")) observer:self]; });

}

Modify it. Click the screen to print out the changed content:

[RACObserve(self.person, name) subscribeNext:^(id  _Nullable x) {

        NSLog(@"Subscriber content %@",x);

    }];

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

    self.person.name = [NSString stringWithFormat:@"%05d",arc4random_uniform(10000)];

}

The above is a simple KVO Demo, mainly RACObserve.

-------------

 

If you return

RACSignal

You can call the subscription directly:

 [[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {

        NSLog(@"%@",x);

    }];

The above is just the foreshadowing. Next, analyze the following circular references:

There are two VC's, A's ViewController has A button to click and jump to B's ViewController.

B's page writes the dealloc method and prints it in the dealloc method: NSLog("8886");

After returning to the ViewController page of pop to A, the print in the dealloc method is executed. But when A circular reference occurs, it does not print.

Here is the code:

- (void)viewilldidload{

 

    [self DemoText];

    [self DemoButton];

    

}

 

- (void)DemoText {

    [[self.testTextField rac_textSignal] subscribeNext:^(NSString * _Nullable x) {

           NSLog(@"%@",x);

    }];

}

 

- (void)DemoButton {

    //The first self is self.view.subviews , self it has a strong reference to the controller.

    [[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {

        NSLog(@"%@",x);

        //In block, when a button listens for a click event, it strongly references self.view.subviews

        self.testTextField.text = @"Hello";

    }];

}

// To test the circular reference, write a dealloc first,

- (void)dealloc {

    NSLog(@"88");

 

The origin of circular references.

OC's traditional solution:__ weak typeof(self) weakSelf = self;

And then self.demoTextFeld.text ... all changed to weakSelf.demoTextFeld ... that's all.

At this time, the printing in dealloc runs normally.

 

//RAC solution to circular reference:

@Webify (self) / / once you write this sentence, the code below it will be automatically marked with weak references or as webself without changing self. It seems that if you use the forech macro loop, the maximum number of weaks is 20.

But when it's written like this, it won't use block if it's used in other places, because webify turns controllers into weak references, and there's no page Jump.

So add a strongify to decorate it.  

If you use Apple's own plus strong, you can replace them one by one. If you use strongify, it will help you traverse and replace them. You don't need to modify the weakSelf one by one. '

 

 

 

For the circular reference of RAC, let's go here for a while, and then improve it later.

Tags: Mobile Attribute iOS

Posted on Fri, 22 May 2020 04:34:07 -0400 by m0rpheu5