访问协议扩展的静态属性 [英] Access static property of protocol extension

查看:35
本文介绍了访问协议扩展的静态属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建一个公开静态属性的协议,然后在该协议的扩展中使用该静态属性,但它似乎只有在我也在协议扩展中定义此静态属性时才有效.基本上是我试图开始工作的代码:

I'm trying to build a protocol exposing a static property, then use that static property in an extension of that protocol, but it seems to work only if I define this static property in the protocol extension as well. Basically the code I'm trying to get to work:

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 属性的注释来使其工作,但是如果我忘记在实现此协议的类中定义此属性,将禁止编译器警告.

This used to work basically as-is in Swift 2, but it's no longer the case in Swift 3. I can get it to work by uncommenting the nibName property in the protocol extension, but that would suppress compiler warnings if I forget to define this property in classes that implement this protocol.

知道我错过了什么吗?谢谢!

Any idea what I'm missing ? Thanks !

作为参考,这里是该代码的 Swift 2.3 版本,可以编译并正常工作:

For reference, here is a Swift 2.3 version of that code that compiles and works without any issue:

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())
    }
}

推荐答案

这在我看来像是一个错误(请参阅相关的错误报告 SR-2992) – 编译器认为 UIViewControllernibName 实例属性和您的 NibInstantiable 协议的 nibName静态属性要求.一个更简单的可重现示例是:

This looks like a bug to me (see the related bug report SR-2992) – the compiler thinks that there's a conflict between UIViewController's nibName instance property and your NibInstantiable protocol's nibName static property requirement. A simpler reproducible example would be:

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 静态属性要求.

A simple workaround would be to just rename your protocol's nibName static property requirement.

这篇关于访问协议扩展的静态属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆