內(nèi)存管理
ReactiveCocoa自己持有全局的所有信號,如果一個(gè)信號有一個(gè)或多個(gè)訂閱者炒事,那么這個(gè)信號就是活躍的臀栈;如果所有的訂閱者都被移除了,那么這個(gè)信號就能被銷毀了挠乳。
那么如何取消訂閱一個(gè)信號呢权薯?
使用dispose
方法
RACDisposable *singal = [self.searchTextField.rac_textSignal subscribeNext:^(id x) {
NSLog(@"value=%@", x);
}];
//在需要取消的時(shí)候調(diào)用
[singal dispose];
循環(huán)引用問題
先看一個(gè)例子
[[self.searchTextField.rac_textSignal map:^id(NSString *text) {
return text.length > 5 ? [UIColor whiteColor] : [UIColor redColor];
}]
subscribeNext:^(UIColor *color) {
self.searchTextField.backgroundColor = color;
}];
subscribeNext:block中使用了self來獲取text field的引用。block會捕獲并持有其作用域內(nèi)的值睡扬。因此盟蚣,如果self和這個(gè)信號之間存在一個(gè)強(qiáng)引用的話,就會造成循環(huán)引用卖怜。循環(huán)引用是否會造成問題屎开,取決于self對象的生命周期。如果self的生命周期是整個(gè)應(yīng)用運(yùn)行時(shí)马靠,比如說本例奄抽,那也就無傷大雅。但是在更復(fù)雜一些的應(yīng)用中甩鳄,就不是這么回事了逞度。
為了避免潛在的循環(huán)引用,Apple建議的做法如下
__weak ViewController *blockSelf = self;
[[self.searchTextField.rac_textSignal map:^id(NSString *text) {
return text.length > 5 ? [UIColor whiteColor] : [UIColor redColor];
}]
subscribeNext:^(UIColor *color) {
blockSelf.searchTextField.backgroundColor = color;
}];
在RAC中還可以這么做
@weakify(self)
[[self.searchTextField.rac_textSignal map:^id(NSString *text) {
return text.length > 5 ? [UIColor whiteColor] : [UIColor redColor];
}]
subscribeNext:^(UIColor *color) {
@strongify(self)
self.searchTextField.backgroundColor = color;
}];
上面的@weakify 和 @strongify 語句是在Extended Objective-C庫中定義的宏妙啃,也被包括在ReactiveCocoa中第晰。@weakify宏讓你創(chuàng)建一個(gè)弱引用的影子對象(如果你需要多個(gè)弱引用,你可以傳入多個(gè)變量),@strongify讓你創(chuàng)建一個(gè)對之前傳入@weakify對象的強(qiáng)引用茁瘦。
最后需要注意的一點(diǎn)品抽,在block中使用實(shí)例變量時(shí)請小心謹(jǐn)慎。這也會導(dǎo)致block捕獲一個(gè)self的強(qiáng)引用甜熔。你可以打開一個(gè)編譯警告圆恤,當(dāng)發(fā)生這個(gè)問題時(shí)能提醒你。在項(xiàng)目的build settings中搜索“retain”腔稀,找到下面顯示的這個(gè)選項(xiàng):
線程
切換到主線程更新UI盆昙,使用deliverOn:[RACScheduler mainThreadScheduler]
這種方式實(shí)現(xiàn),比如在后臺下載圖片焊虏,完成后到主界面顯示圖片
- (RACSignal *)downloadImage
{
RACScheduler *scheduler = [RACScheduler schedulerWithPriority:RACSchedulerPriorityBackground];
NSString *urlString = @"http://img1.qunarzz.com/sight/p0/1603/b0/b014d9f8ab2a5afb90.water.jpg_1190x550_8d26b98e.jpg";
return [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
UIImage *image = [UIImage imageWithData:data];
[subscriber sendNext:image];
[subscriber sendCompleted];
return nil;
}] subscribeOn:scheduler];
}```
[[[self downloadImage] deliverOn:[RACScheduler mainThreadScheduler]]
subscribeNext:^(UIImage *image) {
NSLog(@"Thread:%@ image:%@", [NSThread currentThread], image);
}];
##參考鏈接
[ReactiveCocoa入門教程2](http://benbeng.leanote.com/post/ReactiveCocoaTutorial-part2)