如何给UIViewController瘦身
本文转载至 http://www.cocoachina.com/ios/20141128/10356.html
随着程序逻辑复杂度的提高,你是否也发现了App中一些ViewController的代码行数急剧增多,达到了2、3千行,甚至更多。这时如果想再添加一点功能或者修改现有逻辑变得让人无比头疼。如果你遇到了这类问题,那是时候停下来了,思考一下如何更好地组织代码,给VC瘦身。本文将会阐述如何结合MVC的思想帮你的VC瘦身同时提高复用和可扩展性。
一、开发中常见的现象和缺点
iOS中最常见的一种设计模式就是MVC,但在实际开发过程中,我们因为这样、那样的原因让单纯的ViewController变成了集Model,Controller以及View的一个大集合,这样势必就会导致VC的代码容量呈几何增长。这样的代码会存在以下几个问题:
1、不利于后续维护
代码在一个公司的存活时间通常远长于你在公司的时间,你是否也在接手现有项目以后边看代码边在心里默念“a piece of shit”,我想没有一个人希望之后接手你代码的人有一天看你代码的时候也在心里默念着同样的话。作为一个有追求的程序员,或者说为了不被以后的同事骂,我们必须要为自己的代码负责,避免动辄就是几千行的一个源文件。你自己写的都不愿因看,更何况后续接手的人呢。
如果项目进度很赶,当时没有时间对代码进行合理的拆分和重构,后续也一定要抽出时间来填一下自己挖的坑。你可能会说,公司一直都很忙没有时间留给你去重构。我只能说要不就是你自己不会安排时间,要不就是这个公司只把你当代码搬运工。站在长远发展的角度上,要么改变自己,要么炒了老板。
2、不利于支撑UI的变动
试想如果有一天你们的App的UI风格需要改变,大量的View需要改变,在一个几千行的VC中删删改改是什么感受。可能因为改动UI的时候一个不留神错改了Model或者Controller的东西,导致程序都不能正常运行。而且改动的范围不能控制在一个较小的范围,测试回归起来的工作量也是很大的。
3、不利于复用
如果你的App一开始只支持iPhone版本,所有的一切都那么自然,程序也运行的很好。突然有一天老板告诉你说公司业务发展的不错,为了扩大市场需要退出iPad版,这个时候如果仅仅只是iPhone版本的放大版,那么你需要做的可能就是添加一些view的自适应就好了。但现实并不总是理想,如果iPad版的需要重新设计,按钮的位置都变动了(参考上面的第二点),这个时候难道需要把所有的代码都改一遍?这尼玛工作量也太巨大了吧。
通常iPhone版本和iPad版本不管UI怎么变,业务逻辑只是基本相同的,那么如果当初我们的代码层级比较清晰,是不是Controller和Model层就可以完美的复用呢,针对不同的版本换一套View即可,这个是不是方便多了,自己感受一下。
二、如何解决这些问题
第一部分说了这么多终于点题了,如何使用MVC模式更好的给VC瘦身,提高复用性和可维护性呢?我画了下面一个图:

解释一下上面这幅图,一个完整的模块被分为了三个相对独立的部分,分别是Model,View,Controller,对应到我们App中的依次为继承自NSObject的数据中心,承载UI展示和事件响应的View以及我们最最常用的UIViewController。
其中VC持有View和Model部分,View通过代理或者Target-Action的方式把用户的操作传递给VC,VC负责根据不同的用户行为做出不同响应。如果需要加载或刷新数据则直接调用Model暴露的接口,如果数据可以同步拿到,则直接使用获取到的数据刷新View。如果数据需要通过网络请求等其他异步的方式获取,VC则通过监听Model发出的数据更新(成功或失败)通知,在收到通知时根据成功或者失败对View进行相应的刷新操作。可以看出来整个过程中View和Model是没有直接交互的,所有的操作都是通过VC进行协调的。
进过MVC分层的好处:
1、VC代码量骤降,易于维护
可以看到拆分后VC中就仅剩下事件的响应操作了,所有显示相关的东西都被单独抽取出来,所有的网络请求以及数据缓存都被提取到出去了。VC中的代码会大幅度减少,在我们项目中的实践结果为:拆分前一个VC的代码行数为2600行,拆分后VC的代码行数仅剩不到600行。
2、复用性提高
拆分后如果App需要对UI展示进行大改,那么你的改动基本上都会停留在View模块中,你可以选择在现有的基础上改,也可以选择从写一个。只要业务不变的话,Model和VC模块完全不需要修改。这样改动的范围较小,对开发和测试都比较友好。
拆分后如果App需要支持iPad版本,那么你需要做的就只是重写一个View然后放进去就好了,Model和VC模块同样基本上不要做任何修改,想想是不是还有点儿小激动呢。
三、总结
使用MVC模式可以达到帮VC瘦身,可以到到提高复用性和可维护性的效果,同时也会让原本一个整体的业务代码,分散到各个不同的地方。实际使用中我们需要具体问题具体分析,如果一个VC中的东西本身就很简单,那么完全可以放在一起,因为即使全部放在一起也就几百行代码。例如App中常见的Copyright界面,本身就是加载一个html就搞定了,就完全没必要搞得那么复杂;如果一个VC已经很复杂,代码动辄几千行了,那么就需要拆分,达到更好的复用以及方便维护的目的。
写了几年代码了,见过所有东西都往一个源文件里面塞的,也见过一个本就很简单的东西被设计模式搞的四分五裂的,不要为了用设计模式而用设计模式。把握好度很重要,能用子弹解决的问题就不要动大炮。
代码重构应该是一个持久的过程,在开发的过程中就时不时的对现有不合理的地方进行重构,而不是等待问题已经很多了才想起重构来。千里之行始于足下,千里之堤溃于蚁穴。
如何给UIViewController瘦身的更多相关文章
- iOS:使用MVC模式帮ViewController瘦身
如何给UIViewController瘦身 随着程序逻辑复杂度的提高,你是否也发现了App中一些ViewController的代码行数急剧增多,达到了2,3千行,甚至更多.这时如果想再添加一点功能或者 ...
- iOS UIViewController的瘦身计划
代码的组织结构,以及为何要这样写. 那些场景适合使用子控制器,那些场景应该避免使用子控制器? 分离UITableView的数据源和UITableViewDataSource协议. MVVM的重点是Vi ...
- MVVM与Controller瘦身实践
MVC是一个做iOS开发都知道的设计模式,也是Apple官方推荐的设计模式.实际上,Cocoa Touch就是按照MVC来设计的. 这里,我们先不讲MVC是什么,我们先来谈谈软件设计的一些原则或者说理 ...
- Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
- Android APK瘦身之Android Studio Lint (代码审查)
******** ******** 第一部分: 瘦身内容介绍 ******** ******** 项目新版本的迭代接近尾声, 因为历史累积问题, 导致有很多无效的资源让已经臃肿的APK变得更肿, 因此 ...
- 【直播】APP全量混淆和瘦身技术揭秘
[直播]APP全量混淆和瘦身技术揭秘 近些年来移动APP数量呈现爆炸式的增长,黑产也从原来的PC端转移到了移动端,通过逆向手段造成数据泄漏.源码被盗.APP被山寨.破解后注入病毒或广告现象让用户苦不堪 ...
- APK瘦身记,如何实现高达53%的压缩效果
作者:非戈@阿里移动安全 1.我是怎么思考这件事情的 APK是Android系统安装包的文件格式,关于这个话题其实是一个老生常谈的题目,不论是公司内部,还是外部网络,前人前辈已经总结出很多方法和规律. ...
- iOS可执行文件瘦身方法
缩减iOS安装包大小是很多中大型APP都要做的事,一般首先会对资源文件下手,压缩图片/音频,去除不必要的资源.这些资源优化做完后,我们还可以尝试对可执行文件进行瘦身,项目越大,可执行文件占用的体积越大 ...
- 清理iOS工程里无用的图片,可瘦身ipa
工程在经过多人后,往往会出现较多的垃圾,导致打包出来的ipa文件偏大,有时候我们会通过清理代码来给程序瘦身,而瘦身ipa效果明显的,主要通过清理程序里的无用图片. 推荐一个清理图片的应用 https: ...
随机推荐
- Scrapy笔记:持久化,Feed exports的使用
首先要明确的是,其实所有的FeedExporter都是类,里面封装了一般进行io操作的方法.因此,要怎么输出呢?其实从技术实现来说,在生成item的每一步调用其进行储存都是可以的,只不过为了更加符合s ...
- MQ 分拆Json数据包然后上传
public void UploadInsurHistory() { using (IDbConnection connection = ConnConfig.DmsConnection) { IDb ...
- BZOJ3631 松鼠的新家(树链剖分)
题目链接 松鼠的新家 差不多可以说是树链剖分的模板题了,直接维护即可. #include <bits/stdc++.h> using namespace std; #define REP( ...
- encodeURI 解码 编码
var uriStr = "http://www.baidu.com?name=张三&num=001 zs"; var uriec = encodeURI(uriStr); ...
- 实现一个Java五子棋
五子棋手把手教你写: 写在前面的话: 回想起从前初学代码的五子棋简直写的不像样子.今天闲来无事就写了个五子棋的小程序. 一来呢回忆一下很久以前写代码时的感觉. 二来呢顺便帮下诸位有需求的学生,顺利的C ...
- [原创]Getting Started with Skywalking
Getting Started with Skywalking Pre JDK 1.8+ Skywalking(v3.2.6) (All packages can be download from G ...
- QQ聊天窗口上的广告与QQ弹窗广告的完美屏蔽去除
涉及的软件 1. QQ (笔者的为v8.2版本) 2. Win7 3. ADSafe(3.13.308.9900正式版) 前言 QQ广告十分讨人厌,除了QQ弹窗的广告,让人十分反感外,最近发现QQ聊 ...
- ios开发小结之app发布升级
在近两个月的开发中,遇到了挺多问题的,几天加班加点,最后还是在年前发布并更新了一个版本,欢迎下载无觅下载. 最头疼的问题是提交app审核,之前的工程不太规范,导致一些文件icon没有设置好,直接val ...
- mac搭建安卓开发环境
下载 android studio,利用android studio自带sdk manager下载安卓sdk,在sdk manager中设置相关代理地址,下载完sdk后,在bash_profile中把 ...
- EasyMvc入门教程-高级控件说明(14)列布局控件
想起刚做网页时候,看着这么大的屏幕,一直在 想该如何布局呢,后来经过Table布局,Div布局,Border布局,列式布局. 目前EasyMvc主要支持12列的列式布局(手机兼容性好).请看下面的例子 ...