переопределить инициализатор из универсального класса - PullRequest
0 голосов
/ 15 мая 2018
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?
}

Странно, что нельзя переопределить init в подклассе CheckItem.

Компилятор жалуется, что Initializer не переопределяет указанный инициализатор из своего суперкласса.Он жалуется, что для объявления переопределения требуется ключевое слово override, если я удалю ключевое слово 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.Но жалуется

Не удается преобразовать значение типа «Люди» в ожидаемый тип аргумента «Bool»

при попытке создать новый экземпляр CheckItem.

Кажется, что вывод типа здесь не корректен.

Редактировать

Это работает, когда я развертываю код в swift framework.WTF

1 Ответ

0 голосов
/ 15 мая 2018

Я не уверен, что именно для вас не так.Когда я запускаю ваш код, все выглядит нормально.Вы уверены, что правильно создаете свои экземпляры?

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, который нигде не используется и не является параметром, поэтому вам нужнобыть явным с вашими типами при создании экземпляра, так как вы не передаете тип V в init, и компилятор не может вывести тип.Таким образом, <String, String, Int> или любые другие типы, которые соответствуют ограничениям.

РЕДАКТИРОВАТЬ:

После просмотра кода вашего проекта (проект не запускался на моем Xcode,Я только скопировал соответствующий код в свой проект) Я все еще не вижу проблем - оба инициализатора 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)
    }
}

Создание экземпляров:

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)

Скопируйте, вставьте мой код вдетская площадка и убедитесь сами.Возможно, что-то кроме инициализатора вызывает ошибку.

Для теста вы также можете попробовать закомментировать оба инициализатора CheckItem и создать экземпляр с помощью унаследованного инициализатора.Это должно работать, потому что CheckItem больше не будет иметь своего собственного назначенного инициализатора (https://stackoverflow.com/a/31459131/1433612)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...