RAC <五> 循环引用分析

廉价感情. 提交于 2020-08-10 06:44:04

RAC 可以接管iOS开发中所有的事件,之前文章也说过。虽然学习成本比较大,但是不用RAC的话,很多事件的写法都不太一样,东写一块,西写一块。

RAC 如何取代 KVO?

@property (nonatomic,strong)Person *person;

- (void)viewDidLoad {

    [super viewDidLoad];

    

    //RAC 如何取代 KVO

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

    //监听 name 属性的变化 两个参数 第一个监听对象是谁,第二个监听的属性

    RACObserve(self.person, name);     //一行代码完成 KVO的监听,而且不需要自己去取消监听,RAC已经帮忙做好了。

}

利用上节的查看运行原理:

- (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]; });

}

修改一下,点击屏幕,打印出改变后的内容:

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

        NSLog(@"订阅者内容 %@",x);

    }];

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

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

}

上面就是一个简单的 KVO的 Demo , 主要就是 RACObserve 这个宏。

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

 

如果返回的是 

RACSignal

那么可以直接调用订阅:

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

        NSLog(@"%@",x);

    }];

上面只是铺垫,接下来分析下 循环引用:

有两个 VC ,A的ViewController 有一个按钮点击后 跳转到 B 的ViewController

B的页面写了 dealloc 的方法 ,并在dealloc 方法里打印 :NSLog("8886");

在返回pop到A 的ViewController页面后,执行了 dealloc 方法里的打印。但是当出现循环引用时,并不会打印。

下面是代码:

- (void)viewilldidload{

 

    [self DemoText];

    [self DemoButton];

    

}

 

- (void)DemoText {

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

           NSLog(@"%@",x);

    }];

}

 

- (void)DemoButton {

    //第一个self 它是 self.view.subviews ,self 它对控制器进行了个强引用。

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

        NSLog(@"%@",x);

        //在block (预先准备好的代码),当按钮监听到点击事件以后,它又强引用了 self.view.subviews

        self.testTextField.text = @"Hello";

    }];

}

// 测试循环引用,先写一个 dealloc ,

- (void)dealloc {

    NSLog(@"88");

 

循环引用的由来。

OC传统的解决办法: __weak typeof(self) weakSelf = self;

然后把 self.demoTextFeld.text... 都改成 weakSelf.demoTextFeld... 就可以了。

这个时候,运行 dealloc里的打印正常走了。

 

//RAC 解决循环引用的方法:

@weakify(self) // 一旦写上这句话 它下面的代码,不用改 self. 都自动被打上了 弱引用,也不用修改 self 为 weakSelf. ,看实现的话是用forech 宏循环都打上了weak 好像最大20个数量限制吧。

但是这样一写 ,在别的地方用的话就用不到block了,因为 weakify把 控制器啥的都变成弱引用了,页面一跳转就都没有了。

所以要加一个 strongify来修饰下。 

如果用苹果自己的再加strong也可以 但是那个要一个个替换,用 strongify 的话,已经帮你遍历替换好了,不用再 一个个修改 weakSelf  啥的。‘

 

 

 

关于 RAC的循环引用先暂时到这里,后面再完善下。

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!