如何更好地在项目中管理 Swift 扩展

原文:Medium: Better way to manage swift extensions in your project

该如何管理项目中的扩展(extension)?下面是我项目的截图,它说明了一切。

例如,我有一个简单的扩展 UIColor+Image.swift,它用于通过颜色生成图像。

swift 复制代码
extension UIColor {
    func toImage() -> UIImage {
        // 通过颜色生成图片的方法
    }
}

用法:

swift 复制代码
let redImage = UIColor.red.toImage()

完美,不是吗?

问题

可读性。

  1. 没有人可以轻易地猜到这个函数是来自于原生的 UIColor 类还是来自于我定制的扩展(除非你去阅读源码)。
  2. 这些扩展在不同的项目中是可以重用的,所以我们很可能希望它们能延续到下一个项目中。要猜测它属于哪个命名空间很困难。

解决办法

一个简单而古老的方法是,在我们的扩展中,在所有函数名前添加 _ (下划线)作为前缀。 例如: my_abc_

swift 复制代码
extension UIColor {
    func my_toImage() -> UIImage {
        // 通过颜色生成图片的方法
    }
}

用法:

swift 复制代码
let redImage = UIColor.red.my_toImage()

但是这个解决方案难以管理,因为我们必须确保所有的函数都以 my_ 为前缀。

Swift 协议为我们提供了解决方案

要是我们用 my.toImage() 来代替 my_toImage() 会怎么样?

所以我们的想法是做一个单独的类/结构模块,叫做 MyHelper,它将包含所有的扩展方法。如果你愿意,你也可以将函数分组为扩展方法。

MyHelper.swift

swift 复制代码
import UIKit

public protocol MyHelperCompatible {
    associatedtype someType
    var my: someType { get }
}

public extension MyHelperCompatible {
    var my: MyHelper<Self> {
        get { return MyHelper(self) }
    }
}

public struct MyHelper<Base> {
    let base: Base
    init(_ base: Base) {
        self.base = base
    }
}

// All conformance here
extension UIColor: MyHelperCompatible {}

MyHelperCompatible 协议有一个 "my "变量,它保存了整个 MyHelper 类/结构体对象。

现在,可以根据我们的需求来扩展 MyHelper

例如,UIImage+myHelper.swift

swift 复制代码
import Foundation
import UIKit

extension MyHelper where Base: UIColor {
    func toImage() -> UIImage {
        // 通过颜色生成图片的方法
    }
}

在上面的文件中,我们可以添加与 UIColor 相关的其他辅助函数。同样,我们也可以将所有的函数归入 MyHelper 扩展。

最后,可以像下面这样使用 toImage() 方法:

swift 复制代码
let redImage = UIColor.red.my.toImage()

从现在开始,我们只需要创建像上面一样的扩展和方法。

在任何情况下,如果你想禁用该扩展,可以直接注释/删除一致性部分的代码。

swift 复制代码
// extension UIColor: MyHelperCompatible {}

提示:最好把所有的一致性代码都放在一个地方,而不是分散在项目的各个地方,这样你就可以有更多的控制权。

最后的结论

我知道这似乎有点棘手,需要额外的精力来设置,但相信我,当你的项目增长时,它有很大的帮助。

相关推荐
y先森12 分钟前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy12 分钟前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu108301891115 分钟前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿1 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡2 小时前
commitlint校验git提交信息
前端
虾球xz3 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇3 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒3 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员3 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐3 小时前
前端图像处理(一)
前端