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

如何编写一个通用的Swift类函数来使用闭包初始化类?,swift,generics,self,initializer,Swift,Generics,Self,Initializer,我正在尝试为Swift类编写一个通用类函数,它允许我使用尾随闭包语法初始化类 我已经让它适用于特定的类,比如UILabel //UILabel的扩展 扩展UILabel{ 类func new(u初始化:(inout UILabel)->Void)->UILabel{ var label=UILabel() 初始化(&标签) 退货标签 } } //使用尾随闭包语法和“new”函数初始化新UILabel 让label=UILabel.new{ $0.textColor=.red } 但是,我希望N

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

我已经让它适用于特定的类,比如UILabel

//UILabel的扩展
扩展UILabel{
类func new(u初始化:(inout UILabel)->Void)->UILabel{
var label=UILabel()
初始化(&标签)
退货标签
}
}
//使用尾随闭包语法和“new”函数初始化新UILabel
让label=UILabel.new{
$0.textColor=.red
}
但是,我希望NSObject的所有子类都具有此功能,因此我正在尝试实现上述“new”函数的通用版本。到目前为止,我已经得出了以下结论:

扩展对象{ 类func new(u初始化:(inout Self)->Void)->Self{ var newSelf=Self() 初始化(&newSelf) 返回newSelf } } 但这会产生以下错误:“Self”仅在协议中可用,或作为类中方法的结果;你是说“NSObject”吗?


我正在使用Swift 5.1(Xcode 11 beta)在操场上进行尝试。

正如哈米什所说,也许最好将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
。 然后在协议上写下扩展名

protocol Initializable {
    init()
}

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

extension NSObject: Initializable {}
唯一需要注意的是,您现在不能使用
修饰符,因为您使用的是
协议


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

这无法工作,因为
NSObject
的子类能够将
init
方法标记为
NS\u UNAVAILABLE
。因此,仅仅因为您有一个扩展了
NSObject
的类的元类型对象,并不意味着您可以构造该类型的新对象。那么,只为UIView子类这样做怎么样?这是可能的吗?我会考虑用“x:t,正文:(unt t)抛出->空格)重新定义抛出-> v.x=x;尝试正文(&x);返回x}。然后你可以说
let label=with(UILabel()){…}
。然后,您还可以灵活地使用任何您想要的初始化器。非常好,非常感谢,效果非常好!当您将它与标记为
init
不可用的子类一起使用时,它确实会在运行时崩溃,但现在还可以。只是出于好奇:那我该怎么理解呢?读了这篇文章后,我认为可以在课堂上使用
Self
,正如我第一次打算的那样。