美文网首页
ReactiveCocoa学习笔记二

ReactiveCocoa学习笔记二

作者: c048e8b8e3d7 | 来源:发表于2016-07-07 18:15 被阅读27次

    内存管理

    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”,找到下面显示的这个选项:

    线程

    切换到主线程更新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<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)

    相关文章

      网友评论

          本文标题:ReactiveCocoa学习笔记二

          本文链接:https://www.haomeiwen.com/subject/nwqljttx.html