版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 网址:edu.51CTO.comiOS 代码实践总结前几个月完成对MVVM/RAC的学习之后,最近一直在默默地对项目代码进行重构,写码比较多,过了一段时间回头发现自己的代码风格还有代码质量都有大大的改善。过去几年在一家小公司负责iOS客户端后来负责客户端的研发工作,被杂乱的事情分神比较多,所以到去年的时候,写码已经不太多了。在新公司待了大半年,目前只是写码的小角色,所以精力基本上在写业务代码和业余学习乱七八糟的技术上面。最近一个月除了专门抽时间和精力重构之外,还有就是遇到需要添加功能的模块的时候,由于项目中的代码历史因素比较多,第一件干的事情往往是重构整理代码,发现很多之前的代码写的时候没有
2、注意的事情特别多,比如全局变量乱用;方法没有层次感,胡乱添加;对业务不了解的情况下,通过打补丁的方式实现功能等等。所以我决定写一篇文章,把自己的觉得实践中需要注意的一些事项,具体总结一下分享给大家。减少对象属性这个是最容易改善代码质量的一个点,很多代码一眼看上去就会让人感觉很凌乱,一上来就是几十个不同的对象变量定义在里面,这让不同逻辑之间莫名其妙没法分开。一个是定义的方式不对,很多莫名其妙的内部变量暴露在头文件中,让外部调用者根本不知道哪些才是public可以操作的方法。另外实际上,经过我自己这段时间的重构经验来看,大多数是可以通过局部变量或者_block变量来代替的。1. 头文件中尽可能少暴
3、露变量或方法,而要使用extension或者category放在.m文件,或者专门的private头文件中头文件中暴露的信息越少越好,一切不必要的信息都不要暴露出来m文件的extension中,定义conforms protocol和对象属性,对于对象属性的定义,使用getter/setter 来定义。2. 使用局部变量或者_block变量代替局部变量不需要多说,需要写码的时候思路清晰一些,写完之后在commit之前即使review一定要check一遍,对自己的代码质量负责,code review往往检查不出来冗余或者废弃的代码。不添加一个多余的对象属性,不留注释掉的代码,不留没有用途的代码,
4、这些都是基本功,但是很多开发者就是做不到,或者说对写码没有爱,所以很多废弃的代码,我重构代码的时候,虽然对业务不熟悉,但是大多数模块都能删除掉十分之一的代码和大量的对象属性,这个是单纯的不够用心。关于使用_block变量,这个是Android开发中我感觉到最不满意的地方,这个特性简直太他妈爽了。比如这里,使用block的时候回传一些变量再比如这里,我需要记录一个pan手势开始时,headerView的顶部坐标,结合RAC之后,本来需要全局变量来记录的值,使用_block变量即可搞定3. 可以尽可能避免循环引用有个地方很多开发者会疏漏,在block中使用_XXX对象变量的时候,block会ret
5、ain self指针,一不小心就会造成循环引用的出现。所以使用局部变量的话,就能扼杀这种问题在摇篮之中。减少和模块化对象消息1. 减少对象消息减少UI的action类消息,感谢block和RAC,或者blockskit,让我们得以通过hook来把之前target-action模型换为block来实现,UI和action的代码终于可以一起了,使整个逻辑变得紧凑,在查看代码的时候终于不用跳来跳去了。还有就是日常开发中,把自己写的各种protocol或者传递target/selector的地方,尽量使用block来代替,相信我,这个会使代码好读很多。2. 模块化使用”#pragma mark - X
6、XX”进行分割不同逻辑之间的界限,让整个文件阅读起来更加结构化。还有一个我现在最常用的就是是设置Xcode的快捷键,把Ctrl + 6 显示文档结构的快捷键改为:Command + J ,搜索来快速跳转到对应的消息和模块,要尽量避免文档结构显示超过两屏幕,超过两屏幕说明有点多了,你肯定考虑一下重构了。我个人习惯一般划分的模块有: life cycle,ui helper,datasource/delegate,依据功能进行划分的模块等等,如下是我最近重构的一个ViewController的文档结构MVVM && RAC我自己使用MVVM思路的感觉是太爽了,说一下,MVVM不一定
7、需要使用RAC,但是data binding少不了,在iOS中也就是KVO了,建议大家都去尝试一下,我自己感觉这个基本上MVVM的最核心的东西了,连Android SDK也不得不引入这个特性。把数据部分的逻辑抽取放在ViewModel中,然后让UI和ViewModel中的数据binding,这个不会减少代码量,但是绝对可以大大简化开发时逻辑的复度,再也不用重写-setXXX:方法来update一大堆不相关的UI了,关于UI开发,后面会专门再讲讲新的。这里说一下我自己的理解,有人说RAC影响性能,回调栈太深,这个的确是会有的,但是个人感觉RACObserver是基于KVO实现的,调用的时候是同步
8、调用的,所以对性能的影响有限,也不会出现调用顺序的问题,所以我敢在列表开发中使用data binding,实践之后还好,对用户体验没什么影响。关于RAC,即使你不使用RAC,有一些东西也是绝对值得你在项目中引入的,比如weakify(self)/strongify(self),通过预编译查看的话,这个的做法是设置一个局部变量self来覆盖全局的self,进而避免循环引用的,需要注意的是block层次较深的时候使用的问题。RAC/MVVM,我刚开始学习的时候,写了两篇文章,算是我自己的总结,理解上面还有不足,大家可以通过我博客中文章的参考链接学习。UI开发1. 重写setter方法和Code B
9、lock Evaluation C Extension语法重写UI的getter方法,把UI的初始化放在getter中,减轻 -viewDidLoad的负荷,同时可以使整个页面变得清晰;同时,可以通过使用使用GCC Code Block Evaluation C Extension ()语法,结构化局部变量初始化和处理的逻辑。关于setter代码风格,这个问题之前在我们Q群里探讨之后我也非常认同这种方式写UI。举一个例子,-viewDidLoad中,做为逻辑的入口,代码会变少但是变清晰,代码如下:然后重写bgView的getter方法,包括View和frame这些都可以使用(.)语法使代码结构
10、化层次化:2. 复杂UI的开发有时候我们开发业务的时候,产品需求往往非常复杂,酷炫的UI加上各种考虑全面的逻辑,这个的结果就是,码农的超长代码,而我们平时工作面对的也大多数都是这类问题。关于这个问题,我的解决方式,组合式UI / custom view / child view controller来解决。(1) 组合式view这个概念是从Android中借鉴而来。重构时查看项目中的代码,发现大家用的做UI的时候,对这个概念不是很强烈,感觉是对UIView的view hierarchy理解不够。比如一个复杂的UI,直接把所有的subviews直接堆积到super view上面,这样的结果就是,
11、调整subview的frame非常困难。我个人的做法是,首先对复杂UI进行分块,从左到右或者从上倒下,把各个UI元素放到不同的container view上面,然后组合这些container view放到super view上面,这样的好处非常明显,首先UI干净清晰,阅读起来不那么费劲。其次就是你计算坐标或者设置约束会变得很简单,因为你调整一个UI元素的时候,只需要考虑它与包含它的container view的坐标关系即可,而不是通过一大堆无趣计算跟最外层super view关联起来。还有就是可以充分利用Auto Layout和autoresiziingmask这些UI利器,使用的时候会非常方
12、便。再有就是结合RACObserver这个利器之后,你能很容易做到根据data来update ui。举个例子,是我们项目中前一段时间我重构的一个页面,这个首页列表,性能要求比较高。并没有使用Auto Layout来实现,但是不使用Auto Layout并不是不把它写的很干净的理由。这是我对一个UITableViewCell的分层,最外层由 icon view / right view / bottom view这些container view组成,而right view这个container view则又是由right top view / right middle view /right b
13、ottom view 这些 sub container view组合而成,而具体的UI元素则是放在这些sub container view之中。这样UI代码就会以一种层次化样式展示出来,init/layoutsubviews只需要维护self与container view的关系即可,而具体展示数据的UI元素也只跟sub container view存在坐标关系。我们看一下right view这个container view的代码实现:关于性能的话,感谢iOS,我们不存在Android中页面层次较深性能卡顿的问题,放心把UI层次化就行(2) custom view对于非常复杂并且相对独立或者可以
14、重用的UI,及时使用custom view子类化。对于单纯的展示UI,我们只需要简单通过组合式view就可以实现了。但是有时候,我们会遇到一些包含无论是动画,逻辑都比较复杂的情况,这个时候使用组合式View去实现,一方面容易把逻辑弄混乱,会把文件的文档结构变得很复杂,简单来说就是对象的消息数量很多。这个时候,我们可以通过custom view来实现,实际上这个也是组合式view,但是我们是把这些组合式view变成了一个类而已,只暴露少量的接口给外部调用。如果这个custom view会出现在多个业务模块中,那么有必要使用一个单独的文件来容纳这个类,如果仅仅是这个模块一个使用的话,可以直接写在这
15、个业务模块的文件中即可,没有必要对所有的类都单独一个文件,我们就当作这个“内部类”来弄了。什么时候使用custom view而不是组合view,我想了很久,你觉得组合式view的代码很乱的时候,别客气,包装为一个custom view就行了。我这边最近遇到的几个问题是使用UICollectionView来做部分UI的时候,同时还有其他很多UI元素,我会写一个custom view。比如下面这个文件,把一个左右滑动查看图片的UI使用PhotoView这个custom view进行包装,内部使用UICollectionView实现一部分相对独立的模块,这个时候这个控件实际上是可以包装为一个相对独立
16、的模块的,用子类我感觉比较合适一些。(3) container view controller这个用法很多开发者不熟悉或者说是用的不多,但实际业务中,这个技术非常有用途,可以大大提高开发效率。对于有相对独立业务逻辑以及生命周期要求的业务,使用child view controller进行包装,如果parent view contrller与child view controller之间非常密切,则使用View Model以及block来对parent view controller和 child view controller 进行衔接。使用child view controller来开发UI
17、而不是custom view的优势很多,我个人认为最大优势在于可以方便利用View Controller的生命周期以及View Controller Hierarchy,比如在-viewWillAppear/-viewDidDisappear中做一些操作,再比如直接获取UINavigationController指针等等。之前的做法一般是在View Controller的对应生命周期内调用custom view的方法,传递self.navigationController指针给custom view等。所以可以不仅仅把UI相关的代码包装进入这个child view controller,也可以
18、把网络请求,数据处理这些这些逻辑放到child view controller中,这样下来就能避免那种动不动超过1k行的view controller的出现了。利用MVVM之后,还有一个比较有好处的用法,比如公用一些数据的时候,之前我们是把对象传递来传递去,这样的问题是很容易出现混乱,这个时候我们是传递ViewModel就可以避免这个问题,ViewModel既负责网络请求又负责数据处理,而parent view controller与child view controller所需要做的事情就是跟ViewModel进行binding而已。Auto Layout/Masonry在一些性能要求不是那
19、么强烈的非列表页,我们可以大量使用Auto Layout来开发UI,充分利用UI根据数据的自适应能力,连在container view中调整UI的步骤都不需要了。之前有一段时间我根本不想开发iOS,原因很简单,Android的布局式以及可见式的开发方式非常方便,再加上AS这样的神器,我自己感觉效率不比iOS低。自从项目最低支持变到iOS6之后,我才开始使用Auto Layout,虽然比较费劲,但是感觉这个对UI开发来说是个解脱。至于Masonry这个框架,之前我对这个抱有一定的怀疑不敢使用,所以我把源码读了一遍,发现这个包装很薄很巧妙,很多设计思路也值得借鉴,我读完源码之后,尝试着完全使用Ma
20、nsory来开发一个展示信息的页面,感觉太爽了!这个的优势就是你设置UI的数据之后,不需要再考虑去update ui了,这样世界瞬时就清净了。,下面是我一个简单的示例,结合(.)语法和RAC,可以使用最简单的label这样的命名来对UI设置数据,这个对我们开发UI来说,绝对是一种解脱。说一下Auto Layout的问题:1. 首先一个问题,是如果一个view不是leaf view的话,那么这个UIView如果hidden的话,它的约束仍然是work的,所以会留下空白,不会像Android中那样设置GONE那么方便。国内sunny大神开源一个不错的解决方式,这里说一下我之前的解决方式,比较土逼,
21、直接子类化:2. 动画的问题使用Auto Layout有一个比较大的问题在于动画,通过更改约束来进行动画,一直是我比较头疼的问题,所以一般遇到这类问题的时候,我都会尽量避免使用Auto Layout来解决,而是使用frame的方式来做。3. 多行UILabel的问题iOS7以及以下的操作系统上,UILabel显示多行文本是又不足的,你需要设置UILabel的preferredMaxLayoutWidth为一个固定值才能显示多行文本。在iOS8以后就不再需要设置这个了。4. UIScrollView的问题以及约束歧义和其他问题参考我的文章:这个地方,我的建议是根据具体问题来选择实现方式 :spr
22、ing & structs也好,Auto Layout也好,那种解决问题较为简洁快速就用那种,不一定非要固定于一种行为,尤其是开发的页面有大量动画的时候。注释不要写一堆中文注释,代码不要出现大量的中文,OC已经够啰嗦,不要这么啰嗦地写码。除了提供服务的public功能或者方法,业务代码仅在某些关键点上注释一下就行,不需要一大堆中文,这样太low,代码自注释即可,需要注释的,可以通过喵神的Xcode插件来实现。而对于出现拼音命名代码的人,能做主的话,别犹豫,开掉吧。这里吐一下槽,之前的公司就有这样的哥们,不是我招进来的,老板硬塞给我的。善用OC的新语法OC有很多新的语法糖,可以大大提高我们的效率,参考Apple Guide: 比如打印数字
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 诊所无菌操作制度
- 警务室五个制度
- 2026西安未央湖社区卫生服务中心招聘参考考试试题附答案解析
- 2026上半年云南事业单位联考能源职业技术学院招聘21人备考考试试题附答案解析
- 2026北京协和医院妇科内分泌与生殖中心合同制科研助理招聘参考考试题库附答案解析
- 2026贵州贵阳市息烽县卫生健康局公益性岗位招聘2人备考考试试题附答案解析
- 2026山东济宁曲阜市事业单位公开招聘初级综合类岗位人员备考考试题库附答案解析
- 2026年楚雄州武定县公安局特巡警大队招聘辅警(2人)备考考试题库附答案解析
- 2026贵州遵义清华中学教师招聘4人备考考试题库附答案解析
- 2026年杭州市富阳区春建乡人民政府网格队伍招聘1人备考考试试题附答案解析
- 2026中国国际航空招聘面试题及答案
- (2025年)工会考试附有答案
- 2026年国家电投集团贵州金元股份有限公司招聘备考题库完整参考答案详解
- 复工复产安全知识试题及答案
- 中燃鲁西经管集团招聘笔试题库2026
- 资产接收协议书模板
- 数据中心合作运营方案
- 印铁涂料基础知识
- 工资欠款还款协议书
- 石笼网厂施工技术交底
- 新建粉煤灰填埋场施工方案
评论
0/150
提交评论