我正在尝试为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的所有子类都具有此功能,因此我试图实现上述“新”功能的通用版本。到目前为止,我已经提出了这个建议:
extension NSObject {
class func new(_ initialization: (inout Self) -> Void) -> Self {
var newSelf = Self()
initialization(&newSelf)
return newSelf
}
}
但这会产生以下错误:'Self'仅在协议中可用,或者作为类中方法的结果可用;您是说'NSObject'吗?
我正在使用Swift 5.1(Xcode 11 beta)在操场上尝试这种操作。
答案 0 :(得分:1)
正如 Hamish 所说,也许最好将init放在外面,这样更灵活。但是,使用协议可以对此采取一种解决方法。
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
。
然后在协议上写您的扩展名。
唯一需要注意的是,您现在无法使用class
修饰符,就像您在protocol
中一样。
不确定NS_UNAVAILABLE
修饰符是否会导致问题,我认为当在隐藏init的类上使用它时,它可能在运行时崩溃。