ReactiveCocoa初步了解

2017/10/17 posted in  iOS

ReactiveObjC是一个受到函数响应式编程启发而开发的OC框架,对应的Swift框架叫做ReactiveCocoa or ReactiveSwift。简称为RAC

不同于使用那些被替代和修改的可编辑变量,RAC提供了一个signals (represented by RACSignal)用于捕获当前或者未来的值。这种做法工作起来类似于KVO,但是却没有那么繁琐。

RAC的一大优势就是提供了一个统一的方法去解决异步表现,这些表现包括:委托方法,回调函数块,target-action机制,通知和KVO。

有如下例子:

//当self.name改变后,输出新的名字到控制台
//
//无论何时改变了值,RACObserve(self, username)都会创造了一个新的RACSignal用于发送当前self.name
// 不管在什么时候signal发送了一个新的值,-subscribeNext: 都将执行块方法.
[RACObserve(self, username) subscribeNext:^(NSString *newName) {
    NSLog(@"%@", newName);
}];

但是不想KVO通知,signals是可以被链接和操作的:

// 只输出以"j"开头的名字.
//
// -filter returns a new RACSignal that only sends a new value when its block
// returns YES.
[[RACObserve(self, username)
    filter:^(NSString *newName) {
        return [newName hasPrefix:@"j"];
    }]
    subscribeNext:^(NSString *newName) {
        NSLog(@"%@", newName);
    }];

其实上面代码也可以复杂的写成:

RACSignal *usernameSourceSignal = self.username;
  
RACSignal *filteredUsername =[usernameSourceSignal
  filter:^(NSString *newName) {
        return [newName hasPrefix:@"j"];
    }];
  
[filteredUsername subscribeNext:^(NSString *newName) {
        NSLog(@"%@", newName);
    }];

这是因为RACSignal的每个操作都会返回一个RACsignal,这在术语上叫做连贯接口(fluent interface)。这个功能可以让你直接构建管道,而不用每一步都使用本地变量。

Signals也可以被使用去获取状态。区别于观察属性和设置其他属性来反应新的值,RAC可以按照信号和操作来表达属性:

// Creates a one-way binding so that self.createEnabled will be
// true whenever self.password and self.passwordConfirmation
// are equal.
//
// RAC() is a macro that makes the binding look nicer.
//
// +combineLatest:reduce: takes an array of signals, executes the block with the
// latest value from each signal whenever any of them changes, and returns a new
// RACSignal that sends the return value of that block as values.
RAC(self, createEnabled) = [RACSignal
    combineLatest:@[ RACObserve(self, password), RACObserve(self, passwordConfirmation) ]
    reduce:^(NSString *password, NSString *passwordConfirm) {
        return @([passwordConfirm isEqualToString:password]);
    }];

还有许多用法这就不举例了,详细用例可以查看官方文档

使用时机

刚开始,可能很难理解RAC,因为这个ReactiveObjC很抽象,很难了解什么时机应该使用它,怎样去解决问题。这里有几个推荐的使用时机:

  • 解决异步或者时间驱动的数据源
  • 链接依赖操作(尤其在网络处理方面)
  • 并行独立的工作
  • 简化集合的转变