内容简介:最近一段时间都在进行iOS客户端的重构,参考了许多iOS重构方面的资料,在重构的过程中也遇到一些困难,同时总结了不少经验,在这里和大家分享一下。这将会是一个系列的文章,每一篇文章都会从一个具体的、普遍性的问题出发,然后分析和解决这个问题。插一句,软件开发本身是一件工程化的事情,虽然有一些理论上的指导和支持,但终归还是要从实际项目中出发,找到适合项目本身的最优解。我在这里提到的一些实践不一定适合每一个项目,甚至在某些情况下不适用,所以欢迎大家多多讨论交流,我们的终极目标都是写出具有可读性、可维护性、可拓展性
最近一段时间都在进行iOS客户端的重构,参考了许多iOS重构方面的资料,在重构的过程中也遇到一些困难,同时总结了不少经验,在这里和大家分享一下。这将会是一个系列的文章,每一篇文章都会从一个具体的、普遍性的问题出发,然后分析和解决这个问题。
插一句,软件开发本身是一件工程化的事情,虽然有一些理论上的指导和支持,但终归还是要从实际项目中出发,找到适合项目本身的最优解。我在这里提到的一些实践不一定适合每一个项目,甚至在某些情况下不适用,所以欢迎大家多多讨论交流,我们的终极目标都是写出具有可读性、可维护性、可拓展性的高质量代码。
问题:如何管理界面跳转的代码 回想一下你的项目中,大部分界面跳转的代码是写在哪里的?最简单方便的,直接写在ViewController中。这种方式很好理解,因为ViewController原生就提供了界面跳转的方法prsentVC/pushToVC。 随着项目逐渐复杂,你可能会发现,有一些VC可以从很多不同的VC跳转而来,如果按照原来的方式,就会有很多界面跳转代码的重复。于是我们可能会创建一个XXRouter的类,把跳转到XXViewController的代码提取出来,放到XXRouter中管理。
class XXRouter { var newVC:XXViewController { // 或者从Storyboard/Xib创建 return XXViewController() } func presentXXVC(_ fromVC:UIViewController){ let xxVC = newVC //XXViewController初始化 vc.present(xxVC) } } 复制代码
于是,在其他需要跳转到XXViewController的VC中,只需要新建一个XXRouter,调用router.presentXXVC()就可以实现界面跳转,也做到了统一管理。
class MyViewController:UIViewController { fileprivate var router = XXRouter() func someFunc() { // do something router.presentXXVC() } } 复制代码
这种方式已经能满足我们大部分的要求了,只不过每次都需要创建一个Router实例,当然也可以使用单例。 其实我们可以借助Swift的协议扩展Protocol Extension,可以把Router的实现变得更加直观和优雅
协议扩展Router模式 Swift相比其他OOP语言的一个比较大的特点就是面向协议Protocol Oriented,理论知识这里就不在赘述了,给一个苹果的官方文档的链接Protocol-Oriented Programming in Swift 下面就是我们的实践,这次我们使用protocol来处理我们的界面跳转的代码
protocol XXRouter {} extension XXRouter { var newVC:XXViewController { // 或者从Storyboard/Xib创建 return XXViewController() } func presentXXVC(_ fromVC:UIViewController){ let xxVC = newVC //XXViewController初始化 vc.present(xxVC) } } 复制代码
看起来和之前的实现几乎一模一样,但是在VC中我们就不需要创建XXRouter的实例,而是直接让ViewController实现我们的XXRouter
extension MyViewController:XXRouter{} class MyViewController:UIViewController { func someFunc() { // do something self.presentXXVC(self) } } 复制代码
这种方式还有一个好处就是可以很直观的看到界面间的跳转关系,尤其是一个界面可以跳转到不同界面的情况,比如
extension MyViewController:XXRouter,YYRouter,ZZRouter{} class MyViewController:UIViewController{} 复制代码
上面的代码几乎达到了代码即文档:MyViewController这个界面,可以跳转到XX、YY和ZZ三个ViewController。 更进一步,借助extension的where条件扩展,我们还可以省略掉fromVC呢!
protocol XXRouter {} extension XXRouter where Self:UIViewController { var newVC:XXViewController { // 或者从Storyboard/Xib创建 return XXViewController() } func presentXXVC(){ let xxVC = newVC // XXViewController初始化 // 直接使用self,因为where指定当前扩展的是UIViewController self.present(xxVC) } } 复制代码
这种方式修改的成本很小,只是提取和挪动界面间跳转代码,几乎不会出现什么错误,用非常小的成本很大程度提高了项目代码的可读性和可维护性。目前我们项目中的界面跳转就是用这种方式进行了重构。
其他的跳转方案 最后,再简单分析一下其他两种界面跳转的解决方案
Storyboard
的 segue
跳转
这种方式对于 Storyboard内ViewController
之间的简单跳转来说十分方便,不用写一行代码。而且.storyboard文件中把一个个分离的 ViewController
通过图的方式有机地连接在一起,清晰得展现出了项目内 ViewController
跳转的路径。
不足:涉及到页面之间传值或者需要做额外初始化工作的ViewController,需要在代码中实现delegate,和直接代码跳转相比没有太大差别。
对于需要额外初始化的 ViewController
,把一个跳转流程分离到两个地方实现,个人觉得更加不利于维护。
模仿前端的URL Router跳转,比如MGJRouter
这种方式受Web URL跳转方式的启发,通过注册页面为URL Scheme的方式进行跳转,比较适合Hybird应用,给跳转网页和跳转ViewController一个统一的入口,便于维护
不足:额外多了注册ViewController或实现Router Protocol的操作。 侵入性大,需要在项目初期就使用这种方式,不利于重构。 这篇文章就写到这里啦,iOS重构的文章还有挖了几个坑,近期会填完!如果各位觉得本文对你有帮助的话,请点一个喜欢,谢谢~
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Web Designer's Idea Book, Vol. 2
Patrick McNeil / How / 2010-9-19 / USD 30.00
Web Design Inspiration at a Glance Volume 2 of The Web Designer's Idea Book includes more than 650 new websites arranged thematically, so you can easily find inspiration for your work. Auth......一起来看看 《The Web Designer's Idea Book, Vol. 2》 这本书的介绍吧!