gpt4 book ai didi

swift - 为什么静态成员初始化实例属性时子类类型不可用?

转载 作者:搜寻专家 更新时间:2023-11-01 07:06:47 25 4
gpt4 key购买 nike

当下面的代码运行时,defaultModuleName 中的 selfReactViewController 而人们期望它是 FooViewController。为什么?

class ReactViewController: UIViewController {

var moduleName: String = defaultModuleName

static var defaultModuleName: String {
let t = String(reflecting: self) // Also tried NSStringFromClass
guard let s = t.split(separator: ".").last else { return "" }
guard let r = s.range(of: "ViewController") else { return "" }
return String(s.prefix(upTo: r.lowerBound))
}

}

class FooViewController: ReactViewController {

override func viewDidLoad() {
super.viewDidLoad();
print(moduleName); // Prints "React"
}

}

最佳答案

这很有趣;似乎属性初始化器中可用的 self 只是定义属性的类型,而不是正在构造的实例的动态类型。

一个更简单的例子是:

class C {
static var foo: String { return "\(self)" }
let bar = foo // the implicit 'self' in the call to 'foo' is always C.
}

class D : C {}

print(D().bar) // C

bar 的属性初始化器中,隐含的selfC.self,而不是D.self ;尽管我们正在构造一个 D 实例。这就是对 foo 的调用被视为 self

这也可以防止从属性初始化器调用 class 成员覆盖:

class C {
class var foo: String { return "C" }
let bar = foo
}

class D : C {
override class var foo: String { return "D" }
}

print(D().bar) // C

因此我认为这是一个错误,并且有filed a report here .

在修复之前,一个简单的解决方案是使用 lazy 属性来代替,因为现在 self 是实际实例(在第一次访问该属性时),我们得到的可以用type(of: self)获取动态类型。

例如:

class C {
static var foo: String { return "\(self)" }
// private(set) as the property was a 'let' in the previous example.
lazy private(set) var bar = type(of: self).foo
}

class D : C {}

print(D().bar) // D

应用于您的示例:

class ReactViewController : UIViewController {

lazy var moduleName = type(of: self).defaultModuleName

static var defaultModuleName: String {
let t = String(reflecting: self) // Also tried NSStringFromClass
guard let s = t.split(separator: ".").last else { return "" }
guard let r = s.range(of: "ViewController") else { return "" }
return String(s.prefix(upTo: r.lowerBound))
}
}

class FooViewController : ReactViewController {
override func viewDidLoad() {
super.viewDidLoad()
print(moduleName) // Prints "Foo"
}
}

关于swift - 为什么静态成员初始化实例属性时子类类型不可用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47520296/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com