我想对某个类进行扩展以返回运行时类型对象
例如,我创建了A类的扩展
extension A {
class func niceObject() -> XXXXX { // in objective-c is instancetype
return ....
}
}
所以任何人都知道Swift中有instancetype关键字或者不替换xxxxx
我可以在A的子类上调用此函数而无需手动转换
var b: B = B.niceObject()
由于
答案 0 :(得分:42)
你可以做到。游乐场代码如下。它是self(),niceObject()必须返回。此外,您必须在基类上有一个required
init。
class A {
required init() {
}
func whatClassAmI() -> String {
return "Class A"
}
}
class B: A {
required init() {
super.init()
}
override func whatClassAmI() -> String {
return "Class B"
}
}
let a = A()
let sa = a.whatClassAmI() // "Class A", of course
let b = B()
let sb = b.whatClassAmI() // "Class B", of course
extension A {
class func niceObject() -> Self {
return self.init()
}
}
let aa = A.niceObject()
let saa = aa.whatClassAmI() // "Class A"
let bb = B.niceObject()
let sbb = bb.whatClassAmI() // "Class B", as required
答案 1 :(得分:19)
有两个地方允许使用关键字Self
- 在协议中(参见Jean-Philippe Pellet的回答)和class
方法的结果:
extension A {
class func niceObject() -> Self? {
return nil
}
}
不幸的是,这对您没有帮助,因为以下内容无效
extension A {
class func niceObject() -> Self? {
//A can't be converted to Self
return A()
}
}
错误是由于您从A
class B : A {
}
然后
var b = B.niceObject()
实际上会返回一个A
实例,该实例无法转换为Self
(Self
为B
)
@Grimxn找到了正确的解决方案(See his answer):
您必须向基类添加所需的初始值设定项,例如
class A {
@required init() {
}
}
然后您可以使用self()
extension A {
class func niceObject() -> Self {
return self()
}
}
答案 2 :(得分:10)
至少在procotols中,您可以使用Self
。这代表self
的实际类型。不确定扩展,但是......
例如,请参阅Equatable
:
protocol Equatable {
func ==(lhs: Self, rhs: Self) -> Bool
}
答案 3 :(得分:0)
当您使用Objective-C中的Swift API时,编译器通常会执行直接转换。例如,Swift API func playSong(name: String)
在Objective-C中导入为- (void)playSong:(NSString *)name
。
但是,有一个例外:当你在Objective-C中使用Swift initializer时,编译器会将文本“initWith
”添加到方法的开头,并正确地将第一个字符大写。原始初始化程序。
例如,此Swift初始值设定项init (songName: String, artist: String)
在Objective-C中导入为- (instancetype)initWithSongName:(NSString *)songName artist:(NSString *)artist
。