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?
}
It is weird that, can't override the init in subclass CheckItem.
Compiler complains that Initializer does not override a designated initializer from its superclass. It complains that Overriding declaration requires an 'override' keyword if I remove the override keyword.
It drives me crazy anyone helps? Thanks in advance.
The more weird part is that it works in 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)
}
The full code is available here https://github.com/magerate/TableMaker
Edit
let checkItem = CheckItem<People, Bool>(people, getter: {(p: People) -> Bool in
p.isGirl
})
It compiles if don't try to create any instance of CheckItem. But complains
Cannot convert value of type 'People' to expected argument type 'Bool'
when try to create a new instance of CheckItem.
It seems that type inference is not correctly here.
Edit
It works when I deploy the code to swift framework. WTF
I am not sure what exactly goes wrong for you. When I run your code everything seems fine. Are you sure you're instantiating your instances correctly?
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"
}
In LabelItem
and DataTableItem
you have a generic V
which is not used anywhere and is not a parameter, so you need to be explicit with your types upon instantiation since you're not passing the V
type in the init and the compiler can't infer the type. Thus <String, String, Int>
or any other types that meet the constraints.
EDIT:
After looking into your project code (the project didn't run on my Xcode, I only copied relevant code into my project) I still see no problem - both initializers of CheckItem
compile:
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)
}
}
Creating instances:
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)
Copy paste my code into a playground and see for yourself. Perhaps there is something other than the initializer causing the error.
For a test you can also try commenting out both initializers of CheckItem
and instantiate it with the inherited initializer. That should work, because CheckItem
will not have its own designated initializer anymore (https://stackoverflow.com/a/31459131/1433612)