Reactor是一个Objective-C库,提供编写透明响应式代码的机制。它基于来自Meteor.js的Tracker库,您可以在这里查看其源代码。
以下是一个使用Reactor的响应式函数示例
[MTRReactor autorun:^(MTRComputation *computation) {
self.counterLabel.text = @(self.counter).description;
}];
当计数器属性更新时,它会自动重新运行
for(int i=0 ; i<100 ; i++) {
self.counter++;
}
感觉像有一个魔术师在幕后,对吗?是的!让我们仔细看看他的 DECLARE。Reactor有两个核心组件,MTRComputation
和MTRDependency
,它们通过MTRReactor
秘密链接,以提供响应性。
每次调用-autorun:
时都创建一个MTRComputation
——它是一个封装您传递给它的块的对象。一次只能运行一个计算,正在运行的计算称为
"current computation"
传递给-autorun:
的块会立即调用以更新视图,但它也用于推断这个新计算的依赖项是什么。这怎么发生的?
这是魔术师的身体部位(他用来挥手的方式)
- (NSInteger)counter
{
[self.counterDependency depend];
return _counter;
}
这部分被省略了原始示例。在counter
的访问器中,我们秘密地调用另一个属性,即我们之前创建的counterDependency
的-depend
self.counterDependency = [MTRDependency new]
当对依赖项调用-depend
时,Reactor会查看当前的计算并添加它作为您的依赖项的依赖项。腿,动力系统
- (void)setCounter:(NSInteger)counter
{
_counter = counter;
[self.counterDependency changed];
}
当在依赖项上调用-changed
时,它所有的依赖项计算都将重新运行。这更新了您的UI,重新建立了依赖关系,并再次启动整个周期。它并不那么神奇,对吗?有了腿和身体,您就能像任何魔术师一样。
创建所有这些依赖项非常麻烦。更糟糕的是,如果您覆盖了属性的设置器和获取器以触发依赖项,则存储不再为@synthesized
,您必须手动执行它。
进入MTRReactive
。使用此协议注释您类中的任何类,并将其所有属性隐式设置为响应式
@interface Person : NSObject <MTRReactive>
@property (copy , nonatomic) NSString *name;
@property (assign, nonatomic) NSInteger age;
@end
如果您想将某些属性列入白名单或黑名单,您可以分别实现+reactiveProperties:
或+nonreactiveProperties:
。
请注意以下几点
MTRReactive
并不代表您的属性也是响应式的。希望具有响应式的每个类都必须独立采用该协议。然后你可以在正常计算中像对待对象属性一样对其进行响应。
[MTRReactor autorun:^(MTRComputation *computation) {
self.ageLabel = @(person.age).description;
}];