ReactiveCocoa & MVVM 学习总结二

二. MVVM

1. 什么是MVVM

From: https://github.com/ReactiveCocoa/ReactiveViewModel#model-view-viewmodel

MVVM是指 Model-View-ViewModel的简称,与MVC的一个主要区别是 view 拥有view model。这个与MVC不一样,MVC中应该是controller拥有view。同时,view model 中应该不包含相关view的代码,这样以来,view model就是独立的,可以与任何view进行绑定。

A view model is like an adapter for the model that makes it suitable for presentation. The view model is also where presentation behavior goes.

From: http://cocoasamurai.blogspot.fr/2013/03/basic-mvvm-with-reactivecocoa.html

MVVM是微软提出的,基于MVC的一种设计模式,更准确来说是基于Martin Fowlers Presentation Model (http://martinfowler.com/eaaDev/PresentationModel.html)。在MVVM中,与MVC一样也是有3个组件,但是与MVC还是有区别的。在MVVM中,我们倾向于把ViewController和View放在一个整体中,把他们当做MVVM的View组件。与MVC最主要的不同之处在于,我们引入了View Model,View Model会通过observer的方式把更新推送到View组件中,一般来说observer是通过RAC来实现的。在MVVM中,View Model封装了用于View绑定的数据/属性和一些验证逻辑以及操作。

From: http://www.teehanlax.com/blog/model-view-viewmodel-for-ios/

在MVVM中,the view 和 view controller正式连接在一起被作为一个整体来对待, View。View仍然不会持有model,他们会持有view model。view model可以做很多事情,比如验证用户数据的逻辑,view的展示逻辑,发出网络请求,以及其他各种操作。但是view model有一件事不能做,不能持有任何对view的引用,总之,view model要做到在iOS和OS X都能直接被使用(换句话说,不能 #import UIKit.h)。

当你看到上图时,你会发现我只是使用了两个比较含糊的动词 “notify” 和 “update”,但是并没有说明如何去实现。尽管可以像MVC中那样使用KVO来实现,但是很快你就会发现这样会使代码变得不可控。因此,在实际中,我们最好使用ReactiveCocoa把MVVM中各个部分组合在一起。

在我自己看来,View Model主要是用来获取data(如网络请求读取数据库等),对data进行操作(如验证转换格式等),以及控制用于View绑定的数据和属性,总之,就是各种逻辑操作都可以放到这里处理,最终要做到的就是把数据变为可展示的格式,用于UI进行填充。注意,不要有与UIView相关的代码。

2. MVVM的优势

From: https://github.com/ReactiveCocoa/ReactiveViewModel#model-view-viewmodel

1) View models are testable.  (脱离UI之后,测试起来会非常简单方便,之前MVC中那些比如展示效果之类的测试也很容易就可以做到,而且UI的更改不会影响测试case的开发)

2) View models can be used like models. (这里主要的意思是,view model的操作更加简单,比如可以进行copy和序列化操作,这个用来做类似恢复UI非常有用途)

3) View models are (mostly) platform-agnostic. (大部分情况下,甚至可以做到平台无关,比如跨iPhone/iPad/Mac)

4) Views and view controllers are simpler. (把逻辑放到view model之后,view/view controller就会变得很简洁清晰)

3. 在MVVM中View Controller的职责

绑定View与View Model,响应View Model,调用View Model相应的方法,负责View和window的转换,布局UI,动画,设备旋转,展示UI

4. From: http://www.sprynthesis.com/2014/12/06/reactivecocoa-mvvm-introduction/

1) view-model 作为view controller的一个属性存在,view controller 了解 view-model和它的public属性,但是view-model对view controller却一无所知。

2) view-model 应该只暴露尽可能少的信息给view controller,view controller也根本不需要关心view-model是如何获取数据的,view-model可以通过网络或者验证或者计算或者之前已经存在的数据,这些对view controller都是透明的,它只关心他需要的必须的那些数据。

3) 不必使用一个view-model来负责屏幕上所有的数据,可以使用child view-models来负责那些很小并且容易封装的区域的数据。这在那种有view重用机制(例如 table view cell)的地方非常有用。而对于那些不是可复用的view,则没有必要使用child view-models,只需要把view-model直接传递给那个view即可,这种方式还有一种额外的好处,就可以让所有的subviews的更新保持同步,由于他们绑定了同一个view-model,只要view-model中对应的属性发生变化,所有的subviews都会被update。注: 这个也是我之前很困惑的地方,在做之前公司的项目时,我就曾经遇到类似的问题,当时的解决方式是自己实现了一套KVO机制,不过问题也很明显,就是耦合很重,同时内存处理上也很麻烦。

5. https://github.com/ReactiveCocoa/ReactiveViewModel,这个开源项目默认提供了一个RVMViewModel来作为view model的基类,但是我一直很困惑这个类的用途。参考了一下ash的书,他主要是用RVMViewModel中的active属性来表示view model是否处于激活状态,避免在view model init的时候发起网络请求,而是在view model处于active的时候才发起:

但是这种用法,感觉不是很优雅,使用RACCommand去实现的话,可以比这个要优雅很多,可以参考,http://codeblog.shape.dk/blog/2013/12/05/reactivecocoa-essentials-understanding-and-using-raccommand/,这篇文章里的思想以及我之前的博客中的介绍和github上的demo。网友Sam lau也给我提供了一个他写的小项目作为参考,对学习RAC非常有好处,https://github.com/samlaudev/DesignerNewsForObjc

参考资料:

ReactiveCocoa & MVVM 学习总结二

时间: 2024-12-19 05:20:21

ReactiveCocoa & MVVM 学习总结二的相关文章

【iOS】小项目框架设计(ReactiveCocoa+MVVM+AFNetworking+FMDB)

网址: http://www.saitjr.com/ios/ios-framework-reactivecocoa-mvvmafnetworking-fmdb.html 上一个项目使用到了ReactiveCocoa+MVVM+AFNetworking+FMDB框架设计,从最初的尝试,到后来不断思考和学习,现在对这样一个整体设计还是有了一定了理解与心得.在此与大家分享下. 本文将不再过多的描述ReactiveCocoa.MVVM.FMDB的使用细节.关于ReactiveCocoa,我有一篇实用案例

ReactiveCocoa + MVVM

1.ReactiveCocoa常见操作方法介绍. 1.1 ReactiveCocoa操作须知 所有的信号(RACSignal)都可以进行操作处理,因为所有操作方法都定义在RACStream.h中,而RACSignal继承RACStream. 1.2 ReactiveCocoa操作思想 运用的是Hook(钩子)思想,Hook是一种用于改变API(应用程序编程接口:方法)执行结果的技术. Hook用处:截获API调用的技术. Hook原理:在每次调用一个API返回结果之前,先执行你自己的方法,改变结

ASP.NET MVC学习系列(二)-WebAPI请求

继续接着上文 ASP.NET MVC学习系列(一)-WebAPI初探 来看看对于一般前台页面发起的get和post请求,我们在Web API中要如何来处理. 这里我使用Jquery 来发起异步请求实现数据调用. 继续使用上一文章中的示例,添加一个index.html页面,添加对jquery的引用. 一.无参数Get请求 一般的get请求我们可以使用jquery提供的$.get() 或者$.ajax({type:"get"}) 来实现: 请求的后台Action方法仍为上篇文章中的GetU

Windows API 编程学习记录<二>

恩,开始写Windows API编程第二节吧. 上次介绍了几个关于Windows API编程最基本的概念,但是如果只是看这些概念,估计还是对Windows API不是很了解.这节我们就使用Windows API 让大家来了解下Windows API的用法. 第一个介绍的Windows API 当然是最经典的MessageBox,这个API 的作用就是在电脑上显示一个对话框,我们先来看看这个API的定义吧: int WINAPI MessageBox(HWND hWnd, LPCTSTR lpTe

Caliburn.Micro学习笔记(二)----Actions

Caliburn.Micro学习笔记(二)----Actions 上一篇已经简单说了一下引导类和简单的控件绑定 我的上一个例子里的button自动匹配到ViewModel事件你一定感觉很好玩吧 今天说一下它的Actions,看一下Caliburn.Micro给我们提供了多强大的支持 我们还是从做例子开始 demo的源码下载在文章的最后 例子1.无参数方法调用 点击button把textBox输入的文本弹出来 如果textbox里没有文本button不可点,看一下效果图 看一下前台代码 <Stac

javascript基础学习(二)

javascript的数据类型 学习要点: typeof操作符 五种简单数据类型:Undefined.String.Number.Null.Boolean 引用数据类型:数组和对象 一.typeof操作符 typeof操作符用来检测变量的数据类型,操作符可以操作变量也可以操作字面量. 对变量或值运用typeof操作符得到如下值: undefined----如果变量是Undefined类型: boolean-------如果变量是Boolean类型: number-------如果变量是Numbe

Qt Installer Framework的学习(二)

Qt Installer Framework的学习(二) Qt Installer Framework的一些操作可以使用最常见的Qt项目来表示,也就是说,书写pro文件,使用qmake运行之,除了能够编译正常的项目之外,也可以为项目打包.这里最重要的就是binarycreator了.下面就是我命令行使用binarycreator的时候弹出的一些提示,我们可以根据这样的提示,来了解究竟有哪些使用的方法. 上海萌梦信息科技有限公司(微博:http://weibo.com/qtdream)原创文章,首

2. 蛤蟆Python脚本学习笔记二基本命令畅玩

2. 蛤蟆Python脚本学习笔记二基本命令畅玩 本篇名言:"成功源于发现细节,没有细节就没有机遇,留心细节意味着创造机遇.一件司空见惯的小事或许就可能是打开机遇宝库的钥匙!" 下班回家,咱先来看下一些常用的基本命令. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/48092873 1.  数字和表达式 看下图1一就能说明很多问题: 加法,整除,浮点除,取模,幂乘方等.是不是很直接也很粗暴. 关于上限,蛤蟆不太清楚

Android学习Scroller(二)——ViewGroup调用scrollTo()

MainActivity如下: package cc.ac; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.app.Activity; /** * Demo描述: * 对ViewGroup调用sc