正文
我们在实际开发中偶尔会遇到一些很傻很天真的BUG,结果花了很长时间调试,最后发现这些BUG大多源于一个非常小的问题。最常见的就是在一个字符串中敲错了一两个字母。在实际开发中我们又不得不面对很多读取资源文件的操作,这些操作很多都需要直接操作资源文件名称的字符串来完成。
比如初始化Image
let image = UIImage(named: "checklist_not_completed_20x20_")
注:从Xcode8开始,读取image可以使用Image Literal
Perform Segue
self.performSegue(withIdentifier: "showDetail", sender: self)
这样其实有两个问题:
- 对于字符串Xcode IDE没有代码提示功能,重复敲这些字符串很费时间,并且当字符串稍微复杂点时,你有一定的概率敲错,增加了出BUG的概率。
- Xcode IDE也不会为字符串提供编译时检测,所以如果敲错,你只能等测试出现BUG,然后去查找修复,成本很高。
今天我们就来探讨下怎么优化Segue,来解决我们上面提到的问题。
public protocol CustomSegueProtocol {
associatedtype CustomSegueIdentifier: RawRepresentable
func performCustomSegue(_ segue: CustomSegueIdentifier, sender: Any?)
func customSegueIdentifier(forSegue segue: UIStoryboardSegue) -> CustomSegueIdentifier
}
首先定义一个协议CustomSegueProtocol
,在协议里添加一个关联类型CustomSegueIdentifier
,继承与RawRepresentable
协议。同时声明两个方法performCustomSegue(_::)
和customSegueIdentifier(_:)
extension CustomSegueProtocol where Self: UIViewController,
CustomSegueIdentifier.RawValue == String {
public func performCustomSegue(_ segue: CustomSegueIdentifier, sender: Any?) {
performSegue(withIdentifier: segue.rawValue, sender: sender)
}
public func customSegueIdentifier(forSegue segue: UIStoryboardSegue) -> CustomSegueIdentifier {
guard let identifier = segue.identifier,
let customSegueIndentifier = CustomSegueIdentifier(rawValue: identifier) else {
fatalError("Cannot get custom segue indetifier for segue: \(segue.identifier ?? "").")
}
return customSegueIndentifier
}
}
给CustomSegueProtocol
添加默认实现,并且在添加一些约束。首先我们要求CustomSegueProtocol
协议只能被UIViewController
及其子类使用。其次关联类型CustomSegueIdentifier
的RawValue
为String
,因为我们在storyboard里面设置Segue的identifier只能是String
。具体实现内容比较简单,就是调用Apple原生处理segue的方法。
下面看看具体怎么使用?
class TestCustomSegueViewController: UITableViewController, CustomSegueProtocol {
enum CustomSegueIdentifier: String {
case showNext
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performCustomSegue(.showNext, sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch customSegueIdentifier(forSegue: segue) {
case .showNext:
// Configuration for next page
}
}
}
首先让你的UIViewController
继承CustomSegueProtocol
协议。然后把该协议的关联类型CustomSegueIdentifier
定义为枚举类型,并列出所有的segue。然后在操作segue的时候调用performCustomSegue(_::)
和customSegueIdentifier(_:)
这两个协议函数。
总结
-
通过上面的改造,我们用新的方式来操作segue有以下一些好处:
- Xcode 的代码提示功能,减少了敲错字母引起BUG的概率
- 因为新的
CustomSegueIdentifier
是个强类型,Xcode能在编译时期对其进行类型检测。 - 在
UIViewController
统一用枚举类型定义所有的segue,方便管理维护,同时也可以充分利用枚举一些特性。
-
具体详细代码请参考SwiftDevHints
联系方式
备注
我们在软件开发的过程中,为了提高效率,其中很重要的一环就是把反复使用到的功能或模块封装起来。因此我在GitHub上开源了一个小工具集 - SwiftDevHints,来总结自己在实际项目开发过程中封装的一些小功能。
刚刚介绍的只是其中一个小功能,想看看其它更多功能,请直接点击SwiftDevHints。如果您觉得对您有所帮助,请给一个star吧。
网友评论