本文由CocoaChina-- 微信号 kiss7654321(社区ID)翻译
原文: Protocol-Oriented Segue Identifiers in Swift
原文日期:2015-12-17
8月份时候,我看了 Swift in Practice WWDC15 Session 这个视频,视频的第一部分给我的印象非常深刻,为此我写了一篇博文-- A Beautiful Solution to Non-Optional UIImage Named in Swift 。现在终于抽出时间针对视频的第二部分以及其他更多有趣的地方写篇文章了。
这篇文章是关于如何优雅地处理多个Segue Identifiers的。你猜对了--使用协议。
不幸的是,Segue Identifiers(跳转标识符)是基于字符串的硬编码。当你在Storyboard中添加它们的时候,在每一处相关的代码你都要把这串字符复制过去,拼写错误很可能就会发生。
如果将来你决定更改segue identifier的名称,那你必须在硬编码字符串的每个地方进行修改...这就可能导致潜在的复制粘贴错误或者拼写错误的危险。
为了缓和这种情况,凡是在ViewController中使用1个以上segue identifier时,我都用枚举(enum)来解决这种问题。
但是那也会造成另外一系列的问题,主要是太过臃肿和丑陋。
// ViewController.swift @IBAction func onRedPillButtonTap(sender: AnyObject) { // so this is pretty long... performSegueWithIdentifier(SegueIdentifier.TheRedPillExperience.rawValue, sender: self) } @IBAction func onBluePillButtonTap(sender: AnyObject) { // and so is this... performSegueWithIdentifier(SegueIdentifier.TheBluePillExperience.rawValue, sender: self) }
在prepareForSegue中处理时,问题会变得更加严重
这是我在Swift2.0之前真实的代码。现在你至少可以使用guard来处理,但是仍然不够理想:
无论如何,在整个App的每一个视图控制器中,你都必须解决这个问题,那么你清除这个问题呢?如开篇提到的--使用协议来解决这个问题。
这个解决方案非常优雅,不过并不是我想出来的。感谢苹果今年(2015年)在WWDC上关于架构的演讲。严格来说,这些简直棒极了。
首先,你创建一个SegueHandlerType,它将SegueIdentifier枚举标识为一个类型:
现在你可以使用功能强大的协议扩展为 UIViewController 对象创建基于字符串的 Segueidentifer 枚举:
注意在协议扩展中的方法并没有在协议中申明--它们并不表示被重写(override)。
这是我见到过的最好的使用实例。现在,使用起来非常简单和美观:
从视频中可以看到使用SegueHandlerType的好处包括:
当新添加segues没有被处理的时候,编译器就会报错
重用性
简洁的语法
我们同时也看到了协议的强大
使用协议以及关联类型来加强应用约束
通过一个被约束的协议扩展来共享实现
这里最重要的一点就是利用了编译器的优点。如果你以这种方式构建你的代码,编译器会为你工作,并在犯错的时候提醒你。