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的循环引用先暂时到这里,后面再完善下。
来源:oschina
链接:https://my.oschina.net/u/3619392/blog/4287410