Доступ к статическому свойству расширения протокола

Я пытаюсь создать протокол, раскрывающий статическое свойство, а затем использовать это статическое свойство в расширении этого протокола, но, похоже, это работает, только если я также определяю это статическое свойство в расширении протокола. В основном код, который я пытаюсь заставить работать:

protocol NibInstantiable: class {
    static var bundle: Bundle? { get }
    static var nibName: String { get }
}

extension NibInstantiable where Self: UIViewController {
//    static var nibName: String {
//        return ""
//    }

    static func instantiate() -> Self {
        return Self(nibName: Self.nibName, bundle: Self.bundle ?? Bundle.main)
    }
}

Раньше это работало в основном как есть в Swift 2, но это уже не так в Swift 3. Я могу заставить его работать, раскомментировав свойство nibName в расширении протокола, но это подавит предупреждения компилятора, если я забуду определить это свойство в классах, реализующих этот протокол.

Есть идеи, что мне не хватает? Спасибо !

РЕДАКТИРОВАТЬ: Для справки, вот версия этого кода Swift 2.3, которая компилируется и работает без каких-либо проблем:

protocol Instantiable {
    static var bundle: NSBundle? { get }
    static func instantiate() -> Self
}
extension Instantiable {
    static var bundle: NSBundle? {
        return NSBundle.mainBundle()
    }
}
// MARK: With Nib
protocol NibInstantiable: Instantiable {
    static var nibName: String { get }
}

extension NibInstantiable where Self: UIViewController {
    static func instantiate() -> Self {
        return Self(nibName: Self.nibName, bundle: Self.bundle ?? NSBundle.mainBundle())
    }
}

person axelcdv    schedule 26.12.2016    source источник
comment
Вы уверены, что статическая переменная bundle имеет тип String? Попробуйте добавить актуальный код, это поможет нам решить ваши проблемы. Любое изменение может привести к дополнительным ошибкам.   -  person user28434'mstep    schedule 26.12.2016
comment
Плохо, тип Bundle? (сейчас исправлено). На самом деле здесь нет ничего, кроме фрагмента.   -  person axelcdv    schedule 26.12.2016
comment
Мне это кажется ошибкой — компилятор считает, что существует конфликт между свойством экземпляра UIViewController nibName и вашим требованием статического свойства nibName. См. этот связанный отчет об ошибке. Простое решение — просто переименовать статическое nibName требование. .   -  person Hamish    schedule 26.12.2016
comment
Это было так, спасибо! Не знаю, почему другой ответ был удален, но если вы хотите преобразовать свой комментарий в ответ, я отмечу его как принятый   -  person axelcdv    schedule 27.12.2016
comment
@axelcdv Конечно :)   -  person Hamish    schedule 27.12.2016


Ответы (1)


Мне это кажется ошибкой (см. соответствующий отчет об ошибке SR-2992) — компилятор считает, что существует конфликт между свойством экземпляра UIViewController nibName и вашим Требование к nibName статическому свойству NibInstantiable протокола. Более простой воспроизводимый пример:

protocol Foo {
    static var bar : String { get }
}

class Bar {
    var bar = "" // commenting out this line allows the code to compile
}

extension Foo where Self : Bar {
    static func qux() {
        print(bar) // compiler error: Instance member 'bar' cannot be used on type 'Self'
    }
}

Простым обходным решением было бы просто переименовать требование статического свойства nibName вашего протокола.

person Hamish    schedule 27.12.2016