Swift 5.3中的继承类正在调用上层类init,而不是预期的继承init
我在斯威夫特车上被一件东西绊倒了。 我继承了类Swift 5.3中的继承类正在调用上层类init,而不是预期的继承init,swift,class,inheritance,Swift,Class,Inheritance,我在斯威夫特车上被一件东西绊倒了。 我继承了类UIAlertController,以便在iPadOS和 class myUIAlertController: UIAlertController { convenience init(title: String?, message: String?, preferredStyle: UIAlertController.Style, interfaceIdiom: UIUserInterfaceIdiom? = UIDevice.current.us
UIAlertController
,以便在iPadOS和
class myUIAlertController: UIAlertController {
convenience init(title: String?, message: String?, preferredStyle: UIAlertController.Style, interfaceIdiom: UIUserInterfaceIdiom? = UIDevice.current.userInterfaceIdiom) {
self.init(title: title, message: message, preferredStyle: interfaceIdiom == .pad ? .alert : preferredStyle)
}
现在我遇到了一个问题,当我从这个类创建一个实例时,如下所示:
let actionsheet = myUIAlertController(
title: "Profile.Change-Image.ActionSheet.Title".localized,
message: nil,
preferredStyle: .actionSheet
)
它从UIAlertController
调用init,而不是myUIAlertController
我试过这个:
let actionsheet = myUIAlertController(
title: "Profile.Change-Image.ActionSheet.Title".localized,
message: nil,
preferredStyle: .actionSheet,
interfaceIdiom: UIDevice.current.userInterfaceIdiom
)
这是可行的,但我想知道为什么我需要额外的参数interfaceIdiom
?这个问题与文档中的限制无关,UIAlertController类打算按原样使用,不支持子类化。
独立于基类,当编译器有多个重载函数可供选择时,您总是会遇到此类问题
您的示例与以下内容完全相同:
class Base {
convenience init(value1:Int) {
print("Base::init(\(value1))")
self.init()
}
}
class Derived : Base {
convenience init(value1:Int, value2:Int = 123) {
print("Derived::init (\(value1), \(value2))")
self.init(value1:value1) // no recursion here!
}
}
var b = Base(value1:42) // prints: Base::init(42)
var d1 = Derived(value1:42) // prints: Base::init(42), not Derived::init (42, 123)
var d2 = Derived(value1:42, value2:99) // prints: Derived::init (42, 99) ...
问题是:为什么vard=Derived(value1:42)
调用基类init而不是使用默认参数value2=123
方便地初始化派生类
其原因是编译器如何选择模糊的函数。
考虑两个功能:
func foo() { print ("foo()")}
func foo(_ value:Int = 42) { print ("foo(\(value))")}
如果有人调用foo()
,会发生什么?这两个函数可能都有效,因此编译器必须决定选择哪一个。编译器将选择最特定的匹配函数
第一个foo
始终采用零参数。第二个foo
有时取零,有时取一个参数。因此,第一个函数比第二个函数更具体,因为它总是并且只接受零个参数。因此:
foo() // prints foo(), not foo(42)
从文档中可以看出:
Important-UIAlertController类旨在按原样使用,不支持子类化。
如果您只想强制使用样式,可以使用UIAlertController
上的扩展并生成工厂方法。干杯,错过了黄色的重要框。