从泛型 class 覆盖初始值设定项
override initializer from generic class
open class CheckItem<T, U: Equatable & CustomStringConvertible>: DataTableItem<T,U,Bool> {
public override init(_ data: T, getter: @escaping (T) -> U) {
super.init(data, getter: getter)
}
}
open class DataTableItem<T, U: Equatable & CustomStringConvertible, V: CustomStringConvertible>: TableItem{
let data: T
let getter: (T) -> U
public init(_ data: T, getter: @escaping (T) -> U) {
self.data = data
self.getter = getter
}
}
open class TableItem: NSObject {
public var title: String?
}
奇怪的是,无法覆盖子类 CheckItem 中的 init。
编译器抱怨 Initializer 没有覆盖其超类中的指定初始化程序。如果我删除覆盖关键字,它会抱怨覆盖声明需要 'override' 关键字。
这让我发疯有人帮助吗?提前致谢。
更奇怪的是它在 LabelItem 中工作
open class LabelItem<T, U: Equatable & CustomStringConvertible, V: CustomStringConvertible>: DataTableItem<T,U,V>{
public override init(_ data: T, getter: @escaping (T) -> U) {
super.init(data, getter: getter)
}
完整代码可在此处获得https://github.com/magerate/TableMaker
编辑
let checkItem = CheckItem<People, Bool>(people, getter: {(p: People) -> Bool in
p.isGirl
})
如果不尝试创建 CheckItem 的任何实例,它会编译。但是抱怨
Cannot convert value of type 'People' to expected argument type 'Bool'
当尝试创建 CheckItem 的新实例时。
这里的类型推断似乎不正确。
编辑
当我将代码部署到 swift 框架时它起作用了。卧槽
我不确定您到底出了什么问题。当我 运行 你的代码时,一切似乎都很好。您确定您正确地实例化了您的实例吗?
let checkItem = CheckItem("Check item data") { (string: String) -> String in
return string + "checkItem"
}
let labelItem = LabelItem<String, String, Int>("Label item") { (string: String) -> String in
return string + "labelItem"
}
let dataTableItem = DataTableItem<String, String, Int>("Data table item") { (string: String) -> String in
return string + "dataTableItem"
}
在 LabelItem
和 DataTableItem
中,你有一个通用的 V
,它没有在任何地方使用,也不是参数,所以你需要在实例化时明确你的类型,因为你没有在 init 中传递 V
类型,编译器无法推断类型。因此 <String, String, Int>
或满足约束的任何其他类型。
编辑:
查看您的项目代码后(该项目没有 运行 在我的 Xcode 上,我只是将相关代码复制到我的项目中)我仍然没有发现问题 - [= 的两个初始化程序18=]编译:
open class TableItem: NSObject {
public var title: String?
}
open class DataTableItem<T, U: Equatable & CustomStringConvertible, V: CustomStringConvertible>: TableItem{
let data: T
let getter: (T) -> U
public weak var host: TableItemHost?
public init(_ data: T, getter: @escaping (T) -> U) {
self.data = data
self.getter = getter
}
}
public protocol TableItemHost: class {}
open class CheckItem<T, U: Equatable & CustomStringConvertible>: DataTableItem<T,U,Bool> {
public init(_ data: T, host: TableItemHost, getter: @escaping (T) -> U) {
super.init(data, getter: getter)
self.host = host
}
public override init(_ data: T, getter: @escaping (T) -> U) {
super.init(data, getter: getter)
}
}
正在创建实例:
let checkItem1 = CheckItem("Check item 1 ") { (string: String) -> String in
return string
}
class Host: TableItemHost {}
let host = Host()
let checkItem2 = CheckItem("Check item 2 ", host: host) { (string: String) -> String in
return string
}
print(checkItem1.data)
print(checkItem2.data)
将我的代码复制粘贴到 playground 中并亲自查看。也许除了初始化程序之外还有其他原因导致错误。
对于测试,您还可以尝试注释掉 CheckItem
的两个初始化器并使用继承的初始化器实例化它。那应该可以,因为 CheckItem
将不再有自己的指定初始化程序 ()
open class CheckItem<T, U: Equatable & CustomStringConvertible>: DataTableItem<T,U,Bool> {
public override init(_ data: T, getter: @escaping (T) -> U) {
super.init(data, getter: getter)
}
}
open class DataTableItem<T, U: Equatable & CustomStringConvertible, V: CustomStringConvertible>: TableItem{
let data: T
let getter: (T) -> U
public init(_ data: T, getter: @escaping (T) -> U) {
self.data = data
self.getter = getter
}
}
open class TableItem: NSObject {
public var title: String?
}
奇怪的是,无法覆盖子类 CheckItem 中的 init。
编译器抱怨 Initializer 没有覆盖其超类中的指定初始化程序。如果我删除覆盖关键字,它会抱怨覆盖声明需要 'override' 关键字。
这让我发疯有人帮助吗?提前致谢。
更奇怪的是它在 LabelItem 中工作
open class LabelItem<T, U: Equatable & CustomStringConvertible, V: CustomStringConvertible>: DataTableItem<T,U,V>{
public override init(_ data: T, getter: @escaping (T) -> U) {
super.init(data, getter: getter)
}
完整代码可在此处获得https://github.com/magerate/TableMaker
编辑
let checkItem = CheckItem<People, Bool>(people, getter: {(p: People) -> Bool in
p.isGirl
})
如果不尝试创建 CheckItem 的任何实例,它会编译。但是抱怨
Cannot convert value of type 'People' to expected argument type 'Bool'
当尝试创建 CheckItem 的新实例时。
这里的类型推断似乎不正确。
编辑
当我将代码部署到 swift 框架时它起作用了。卧槽
我不确定您到底出了什么问题。当我 运行 你的代码时,一切似乎都很好。您确定您正确地实例化了您的实例吗?
let checkItem = CheckItem("Check item data") { (string: String) -> String in
return string + "checkItem"
}
let labelItem = LabelItem<String, String, Int>("Label item") { (string: String) -> String in
return string + "labelItem"
}
let dataTableItem = DataTableItem<String, String, Int>("Data table item") { (string: String) -> String in
return string + "dataTableItem"
}
在 LabelItem
和 DataTableItem
中,你有一个通用的 V
,它没有在任何地方使用,也不是参数,所以你需要在实例化时明确你的类型,因为你没有在 init 中传递 V
类型,编译器无法推断类型。因此 <String, String, Int>
或满足约束的任何其他类型。
编辑:
查看您的项目代码后(该项目没有 运行 在我的 Xcode 上,我只是将相关代码复制到我的项目中)我仍然没有发现问题 - [= 的两个初始化程序18=]编译:
open class TableItem: NSObject {
public var title: String?
}
open class DataTableItem<T, U: Equatable & CustomStringConvertible, V: CustomStringConvertible>: TableItem{
let data: T
let getter: (T) -> U
public weak var host: TableItemHost?
public init(_ data: T, getter: @escaping (T) -> U) {
self.data = data
self.getter = getter
}
}
public protocol TableItemHost: class {}
open class CheckItem<T, U: Equatable & CustomStringConvertible>: DataTableItem<T,U,Bool> {
public init(_ data: T, host: TableItemHost, getter: @escaping (T) -> U) {
super.init(data, getter: getter)
self.host = host
}
public override init(_ data: T, getter: @escaping (T) -> U) {
super.init(data, getter: getter)
}
}
正在创建实例:
let checkItem1 = CheckItem("Check item 1 ") { (string: String) -> String in
return string
}
class Host: TableItemHost {}
let host = Host()
let checkItem2 = CheckItem("Check item 2 ", host: host) { (string: String) -> String in
return string
}
print(checkItem1.data)
print(checkItem2.data)
将我的代码复制粘贴到 playground 中并亲自查看。也许除了初始化程序之外还有其他原因导致错误。
对于测试,您还可以尝试注释掉 CheckItem
的两个初始化器并使用继承的初始化器实例化它。那应该可以,因为 CheckItem
将不再有自己的指定初始化程序 (