swift - 如何编写一个通用的 Swift 类函数来使用闭包初始化类?

标签 swift generics self initializer

我正在尝试为 Swift 类编写一个通用类函数,它允许我使用尾随闭包语法来初始化类。

我已经让它适用于特定类,例如 UILabel。

// Extension for UILabel
extension UILabel {
    class func new(_ initialization: (inout UILabel) -> Void) -> UILabel {
        var label = UILabel()
        initialization(&label)
        return label
    }
}

// Initialize new UILabel using trailing closure syntax and "new" function
let label = UILabel.new {
    $0.textColor = .red
}

但是,我想为 NSObject 的所有子类都提供此功能,因此我正在尝试实现上面"new"函数的通用版本。到目前为止,我想出了这个:

extension NSObject {
    class func new(_ initialization: (inout Self) -> Void) -> Self {
        var newSelf = Self()
        initialization(&newSelf)
        return newSelf
    }
}

但这会产生以下错误:'Self' 仅在协议(protocol)中可用或作为类中方法的结果可用;您是指“NSObject”吗?

我正在使用 Swift 5.1(Xcode 11 测试版)在 Playground 上进行尝试。

最佳答案

正如 Hamish 所说,也许最好将 init 留在外面,这样更灵活。然而,可能有一种使用协议(protocol)的解决方法。

protocol Initializable {
    init()
}

extension Initializable {
    static func new(_ initialization: (inout Self) -> Void) -> Self {
        var newSelf = Self()
        initialization(&newSelf)
        return newSelf
    }
}

extension NSObject: Initializable {}

NSObject 已经有一个 init 所以它自动符合 Initializable。 然后在协议(protocol)上写下你的扩展。

唯一要注意的是,您现在不能使用 class 修饰符,因为您在 protocol 中。

不确定这是否会导致 NS_UNAVAILABLE 修饰符出现问题,我认为当您在隐藏 init 的类上使用它时它可能会在运行时崩溃。

关于swift - 如何编写一个通用的 Swift 类函数来使用闭包初始化类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56465632/

相关文章:

ios - 启动图像和打开动画是否导致我的应用程序卡住?

ios - 如何将整个可滚动的 UITableView 保存为 PNG

Java 1.6 : Creating an array of List<T>

使用泛型参数的Java方法?

ios - 我怎样才能得到真正的 'self' ,哪个节点运行 SKaction 序列

ios - 查看 Controller 和自身

ios - 如何使用套接字编程将 iOS Swift 应用程序连接到硬件设备?

ios - 循环解析后重新加载数据

generics - typescript :强制默认通用类型为 `any` 而不是 `{}`

python - 了解 `self` 和 `cls` 之间的区别以及它们是否引用相同的属性