2016-12-26 36 views
1

我想构建一个协议公开一个静态属性,然后在该协议的扩展中使用该静态属性,但它似乎工作,只有当我在协议扩展中定义此静态属性以及。 基本上我试图让工作代码:访问协议扩展的静态属性

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

这曾经的基本工作原理为,在斯威夫特2,但它不再是斯威夫特3的情况下,我可以得到它通过取消注释工作协议扩展中的nibName属性,但如果我忘记在实现此协议的类中定义此属性,则会抑制编译器警告。

任何想法我失踪? 谢谢!

编辑:供参考,在这里是一个雨燕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()) 
    } 
} 
+0

你确定静态变量'bundle'有'String'类型吗?尝试添加实际的代码,它会帮助我们帮助你解决你的问题。任何更改都可能会引入其他错误。 – user28434

+0

我的不好,类型是'Bundle?'(现在修复)。其实没有比这里的片段更多的了。 – axelcdv

+1

这对我来说看起来像一个bug - 编译器认为'UIViewController'的'nibName'实例属性和你的静态'nibName'属性需求之间存在冲突。查看[这个相关的bug报告](https://bugs.swift.org/browse/SR-2992) - 一个简单的解决方案就是重命名你的静态'nibName'需求。 – Hamish

回答

1

这看起来像我的错误(请参阅相关的bug报告SR-2992) - 中编译器认为UIViewControllernibName实例属性与您的NibInstantiable协议的nibName静态属性要求之间存在冲突。一个简单重复的例子是:

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