ReactiveCocoa学习笔记二

内存管理

ReactiveCocoa自己持有全局的所有信号,如果一个信号有一个或多个订阅者,那么这个信号就是活跃的;如果所有的订阅者都被移除了,那么这个信号就能被销毁了。
那么如何取消订阅一个信号呢?
使用dispose方法

    RACDisposable *singal = [self.searchTextField.rac_textSignal subscribeNext:^(id x) {
        NSLog(@"value=%@", x);
    }];
    
    //在需要取消的时候调用
    [singal dispose];

循环引用问题

先看一个例子

    [[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会捕获并持有其作用域内的值。因此,如果self和这个信号之间存在一个强引用的话,就会造成循环引用。循环引用是否会造成问题,取决于self对象的生命周期。如果self的生命周期是整个应用运行时,比如说本例,那也就无伤大雅。但是在更复杂一些的应用中,就不是这么回事了。
为了避免潜在的循环引用,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宏让你创建一个弱引用的影子对象(如果你需要多个弱引用,你可以传入多个变量),@strongify让你创建一个对之前传入@weakify对象的强引用。
最后需要注意的一点,在block中使用实例变量时请小心谨慎。这也会导致block捕获一个self的强引用。你可以打开一个编译警告,当发生这个问题时能提醒你。在项目的build settings中搜索“retain”,找到下面显示的这个选项:

ReactiveCocoa学习笔记二_第1张图片

线程

切换到主线程更新UI,使用deliverOn:[RACScheduler mainThreadScheduler]这种方式实现,比如在后台下载图片,完成后到主界面显示图片

- (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 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)

你可能感兴趣的:(ReactiveCocoa学习笔记二)