ios mvvm框架的封装_iOS MVVM+RAC 从框架到实战

一、前言

很早之前就想写写自己在架构模式方面的心得,但是一直感觉自己是井底之蛙,毕竟在iOS领域越深入越感到自己的无知,心中有着敬畏之心,就更没有自信去写这个东西(你也可以理解是没时间(>﹏<),请原谅我的装逼,嘿嘿).

对于架构模式这个让人又爱又恨的玩意,说来其实简单,但一千个人眼中就有一千种哈姆雷特,说他千变万化确实是事实,而且当你深入其中的时候你真的会上瘾,并乐此不疲!

前几天自己写的一篇《iOS Xcode全面剖析》阅读量在短短一天内破千,还上了简书首页(你看这句话字体就知道不是广告了( ⊙o⊙ )),确实很开心,昨天又跟我一朋友用代码讲解了我对MVVM的理解及运用,此情此景下,脑袋一热搞出一篇来分享给大家也情有可原,当然更希望有更多的大神来指点一下,让我自己也让大家有提升就够了,万分感谢!

二、谈谈MVVM和RAC

1、MVVM浅析

到这里我就默认你看过MVVM相关文章(毕竟相关文章已经可以用满天飞来形容了~(≧▽≦)/~啦啦啦!),仅仅简要谈谈我对其的理解。

MVC是构建iOS App的标准模式,是苹果推荐的一个用来组织代码的权威范式,市面上大部分App都是这样构建的,具体组建模式不细说,iOS入门者都比较了解(虽然不一定能完全去遵守),但其几个不能避免的问题却是很严重困扰开发者比如厚重的ViewController、遗失的网络逻辑(没有属于它的位置)、较差的可测试性等因此也就会有维护性较强、耦合性很低的一种新架构MVVM (MVC 引申出得新的架构)的流行。

MVVM虽然来自微软,但是不应该反对它,它正式规范了正式规范了视图和控制器紧耦合的性质,如下图:

ViewModel: 相比较于MVC新引入的视图模型。是视图显示逻辑、验证逻辑、网络请求等代码存放的地方,唯一要注意的是,任何视图本身的引用都不应该放在VM中,换句话说就是VM中不要引入UIKit.h (对于image这个,也有人将其看做数据来处理,这就看个人想法了,并不影响整体的架构)。

这样,首先解决了VC臃肿的问题,将逻辑代码、网络请求等都写入了VM中,然后又由于VM中包含了所有的展示逻辑而且不会引用V,所以它是可以通过编程充分测试的。

so,就是这个样子的,6666!

2、RAC浅浅析

特别浅。。。本文重点是框架及实战及MVVM思想,RAC这玩意话说学习曲线较长,难以理解,不好上手,是因为之前学习的时候使用者、中文教程还比较少,所以学习运用起来比较费劲,(当时确实废了好大得劲,实力装逼一把 @%&$%& )但现在已经成熟的烂大街了,只要有心,好的教程一大把,能潜下心来看我写的水文的人,拿下RAC不在话下!

ReactiveCocoa 可以说是结合了函数式编程和响应式编程的框架,也可称其为函数响应式编程(FRP)框架,强调一点,RAC虽然最大的优点是提供了一个单一的、统一的方法去处理异步的行为,包括delegate方法,blocks回调,target-action机制,notifications和KVO.但是不要简单的只是单纯的认为他仅仅就是减少代码复杂度,更好的配合MVVM而已,小伙子,这样你就小看它了。

它最大的与众不同是提供了一种新的写代码的思维,由于RAC将Cocoa中KVO、UIKit event、delegate、selector等都增加了RAC支持,所以都不用去做很多跨函数的事。

如果全工程都使用RAC来实现,对于同一个业务逻辑终于可以在同一块代码里完成了,将UI事件,逻辑处理,文件或数据库操作,异步网络请求,UI结果显示,这一大套统统用函数式编程的思路嵌套起来,进入页面时搭建好这所有的关系,用户点击后妥妥的等着这一套联系一个个的按期望的逻辑和次序触发,最后显示给用户。

额,就说这么多,再说就没头了~(≧▽≦)/~啦啦啦!

3、本篇对两者的理解运用

在此次介绍中,会使用MVVM+RAC结合的方式,搞定一个添加上拉加载及下拉刷新的列表,所以更多的诠释MVVM思想,而不是RAC的逻辑链式操作(这一点用登录界面来写更能体现Y^o^Y ),RAC在此扮演的更大一部分的角色是更好的解耦,减少代码复杂度,使代码层次分明、逻辑清晰更便于维护升级。

三、框架部分

1、框架目录详解

首先介绍一下本框架的目录结构,如下图

1)Frameworks

存放系统库的虚拟文件夹, 目前搭建框架的时候需要手动添加一个名称为Frameworks的虚拟文件夹,这样你在Build Phases 中添加的系统库会自动归入此文件夹,不会直接在外部显示以至于打乱目录结构。系统库添加流程如下:

另外,细心地家伙会发现此目录中有两个相同的Frameworks, 那这到底是什么鬼?最上面的那个Frameworks是在自己搭框架自己添加的,当时的项目还很单纯, 没有这么淘气,问题出在下面那个Pods Target上,添加它之后就会自动给你生成一个虚拟的Frameworks的文件夹,那又该问了为啥不直接用下面那个呢???(废话真多!反正也没冲突,就留着吧╮(╯﹏╰)╭)

既然提到了Pods,那接下来讲讲CocoaPods(第三方类库管理工具)。

2)CocoaPods

当你开发iOS应用时,会经常使用到很多第三方开源类库,比如JSONKit,AFNetWorking等等。可能某个类库又用到其他类库,所以要使用它,必须得另外下载其他类库,而其他类库又用到其他类库,“子子孙孙无穷尽也”,反正在早期我是体会过这种痛苦,好心酸,手动一个个去下载所需类库是十分麻烦的。

还有另外一种常见情况是,你项目中用到的类库有更新,你必须得重新下载新版本,重新加入到项目中,十分麻烦。

CocoaPods就是帮你解决上面的问题的,话说这玩意应该是iOS最常用最有名的类库管理工具了,作为iOS程序员的我们,掌握CocoaPods的使用是必不可少的基本技能了,至于这玩意该咋用?

O(∩_∩)O哈哈~你觉得我会告诉你么?好吧,我这人还是很心软的,下面一张图告诉你该咋用...

哎呦,不错哦~是不是get了一个新技能 ?6666!

3)AppDelegate

这个目录下放的是AppDelegate.h(.m)文件,是整个应用的入口文件,所以单独拿出来。一会儿告诉你如何写一个简洁的AppDelegate,会在这个文件夹里添加一些类,所以将其放入一个文件夹内还是很有必要的。

4)Class

工程主体类, 日常大部分开发代码均在这里,又细分了好多次级目录。

通用类General : 通用类(文件夹项目移植过程中都不需要更改的就能直接使用的)

Base : 基类 (整个框架的基类)

Categories : 公共扩展类 (就是一些常用的类别,比如分享啊什么的)

Core : 公共核心类(一般存放个人信息、接口API等)

Models : 公共Model (公用的一些数据模型)

Views : 公共View (封装的一些常用的View)

工具类Helpers : 工程的相关辅助类(比如类似数据请求、表单上传、网络监测等工具类)

宏定义类Macro : 宏定义类 (就是整个应用会用到的宏定义)

AppMacro.h app项目的相关宏定义

NotificationMacro.h 通知相关的宏定义

VendorMacro.h 第三方相关宏定义

UtilsMacro.h 为简化代码的宏定义

...等等等等(其他随你定啦!Y^o^Y )

APP具体模块代码类Sections : 各模块的文件夹(一般而言,我们以人为单位)

LSSections 王隆帅的文件夹

CLSections 马成麟的文件夹

...等等等等(也可以写你最喜欢的苍老师的,叼叼的!)

每个成员的文件夹下是其所负责模块的文件夹,比如苍老师负责PHP界面模块(我也认为PHP是最好的语言!大家可以在评论区谈论一下!),如下(接着上面的个人文件夹):PHP : 模块名,也可以是首页(HomePage)...等等

ViewControllers 界面控制器存放处(这是文件夹名)

ViewModels 打杂的(MVVM的核心、解耦合、处理逻辑等)

Views 界面相关View存放处(界面相关子View)

Models 数据模型存放处(各种单纯的数据模型,一点都不胖,是标准的瘦Model)

这就是标准的MVVM了。。。为啥不和上面目录连起来呢?为啥呢?为啥呢?因为臣妾做不到啊!!!(不会三级、四级列表的MarkDown写法,求大神支招!良辰必有重谢!)

第三方类库Vendors : 第三方的类库/SDK,如UMeng、WeiboSDK、WeixinSDK等等。

到这哥们又该疑惑了,心里该碎碎念了:What are you 弄啥嘞!刚才刚讲了个第三方库管理CocoaPods,你丫这里自己又搞了一个,信不信我突突了你!

哈哈哈,刚才的CocoaPods确实管理着大部分的第三方库,这里建立第三方库目录的原因有两个:其一,并不是所有的你需要的第三方都支持pods的,所以还是需要手动添加一些类库。其二,一些第三方库虽然支持pods,但是需要我们去更改甚至自定义这个第三方,此时也需要放入这里,也防止使用pods一不小心更新掉你的自定义!:-D你来打我啊!

5)Resource

这里放置的是工程所需的一些资源,如下Fonts 字体

Images 图片(当然你可以添加至Assets.xcassets, 没人拦着你)

Sounds 声音

Videos 视频

ok,目录就讲到这里!想知道更详细的可以私信我!

2、基类详解

这里着重讲解一下VC、V、VM的基类,其他的模式与View类似所以略过,其中TableViewCell的基类稍微特殊所以也提一下。

我目前的基类如下图:

是不是眼花缭乱了..., 我曾经也看它不顺眼, 曾经尝试过把基类都干掉,然后遇到了一些麻烦...就妥协了,在文章的最后可以跟大家聊聊我是怎么去干掉基类,然后又失败的,这里先详细讲一下基类。

1)YDViewController

函数的具体用意图已经标的很清楚了,这里简单讲一下四个函数的作用yd_addSubviews : 添加View到ViewController

yd_bindViewModel : 用来绑定V(VC)与VM

yd_layoutNavigation : 设置导航栏、分栏

yd_getNewData : 初次获取数据的时候调用(不是特别必要)

2)YDView

yd_setupViews : 添加子View到主View

yd_bindViewModel : 绑定V与VM

yd_addReturnKeyBoard : 设置点击空白键盘回收

3)YDViewModel

yc_initialize : 进行一些逻辑绑定,网络数据请求处理。

LSRefreshDataStatus 数据处理后需要进行的操作标识

LSHeaderRefresh_HasMoreData 下拉还有更多数据

LSHeaderRefresh_HasNoMoreData 下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值