项目中使用 ReactiveCocoa 一般都会嵌入 ReactiveViewModel 或者 ReactiveCocoaLayout 联合处理UI、网络、动画、布局、窗口切换等,组合使用时威力惊人。
github地址:https://github.com/ReactiveCocoa/ReactiveViewModel
https://github.com/ReactiveCocoa/ReactiveCocoaLayout
官网介绍主要优点:
1.视图模型是可测试的。因为他们并不需要一个视图来做好自己的工作,演示行为没有任何的UI自动化或存根进行测试。
2.查看模型可用于像模型。如果需要,视图模型可以被复制或序列化就像一个领域模型。这可以用来快速地实现UI修复及类似行为。
3.视图模型(大部分)平台无关的。由于实际的UI代码住在视图中,精心设计视图模型可以用来在iPhone ,iPad和Mac的,只有轻微的调整为每个平台。
4.视图和视图控制器简单。一旦重要的逻辑移到别处,意见和风险投资成为愚蠢的UI对象。这使得他们更容易理解和重新设计。
总之,随着MVVM取代MVC可能导致更多的灵活和严格的UI代码
MVVM是一个功能强大的数据绑定系统最成功的。 ReactiveCocoa是一个这样的系统。
通过模拟变化的信号,视图模型可在不实际需要知道它的存在(同样为模型→视图模型通信)进行通信的看法。这种分离是为什么视图模型可以在未达成视图进行测试 - 测试只需要连接到虚拟机的信号,并验证行为是正确的。
如果各位做过wpf、Silverlight 开发,就明白其中binding,action 实现所在了。
看看具体实例:
结构:
-ASHDetailViewController.h -ASHDetailViewController.m -ASHDetailViewModel.h -> RVMViewModel.h -ASHDetailViewModel.m ........
Viewcontroller:
@class ASHDetailViewModel; @interface ASHDetailViewController : UIViewController @property (strong, nonatomic) ASHDetailViewModel *viewModel; @end
Model:
#import "RVMViewModel.h" @class ASHTimerViewModel; @interface ASHDetailViewModel : RVMViewModel @property (nonatomic, readonly) NSString *recipeName; @property (nonatomic, readonly) NSString *recipeDescription; @property (nonatomic, readonly) NSString *recipeFilmTypeString; @property (nonatomic, readonly) NSInteger numberOfSteps; @property (nonatomic, readonly) BOOL canStartTimer; -(NSString *)titleForStepAtIndex:(NSInteger)index; -(NSString *)subtitleForStepAtIndex:(NSInteger)index; -(ASHTimerViewModel *)timerViewModel; @end
Navigation:
#pragma mark - Navigation - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@"showDetail"]) { NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; ASHDetailViewController *viewController = segue.destinationViewController; viewController.viewModel = [self.viewModel detailViewModelForIndexPath:indexPath]; } }
/*! * // Whether the view model is currently "active." // // This generally implies that the associated view is visible. When set to NO, // the view model should throttle or cancel low-priority or UI-related work. // // This property defaults to NO. */ -(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; self.viewModel.active = YES; }