Swift 中的扩展属性冲突子类声明

Posted

技术标签:

【中文标题】Swift 中的扩展属性冲突子类声明【英文标题】:Extension property conflicting subclass declaration in Swift 【发布时间】:2016-07-12 10:38:10 【问题描述】:

我在 XCode 7.3 中有一个 Swift 2 项目,其中我使用了两个不同的第三方框架。

'FrameworkA' 声明一个公共的 UIView 扩展,声明 cornerRadius 属性,如下所示:

extension UIView 
    var cornerRadius: CGFloat 
        get  return self.layer.cornerRadius 
        set(cornerRadius) 
            self.layer.masksToBounds = true
            self.layer.cornerRadius = cornerRadius
        
    

'FrameworkB' 声明了一个带有cornerRadius 属性的UIView 子类:

class TagView: UIView 
    var cornerRadius: CGFloat = 0 
        didSet 
            layer.cornerRadius = cornerRadius
            layer.masksToBounds = cornerRadius > 0
        
    

两个框架都编译得非常好,因为它们彼此不认识。但是,当尝试在我的代码中使用“FrameworkB”属性时:

let view = UIView()
view.cornerRadius = 10    // FrameworkA: Ok

let tagView = TagView(title: "")
tagView.cornerRadius = 10    // Compilation error
(tagView as UIView).cornerRadius = 10    // FrameworkA: Ok

它失败并出现错误:

“cornerRadius”的模糊使用

我可以调用“FrameworkA”扩展属性类型转换为UIView,但即使我没有在此文件中导入“FrameworkA”,我也无法调用“FrameworkB”类属性。一旦我在项目的某处导入“FrameworkA”,它就会开始失败。

有没有办法明确告诉编译器使用“FrameworkB”方法或避免在 Swift 文件中导入“FrameworkA”?

编辑:要重现它,您可以使用WakupTagListView pod(分别为FrameworkA 和FrameworkB)并尝试执行上面的代码。

【问题讨论】:

如果你使用(tagView as TagView).cornerRadius = 10(tagView as TagListView.TagView).cornerRadius = 10会发生什么 @LukeVanIn 同样的错误。我不认为这有什么不同,因为tagView 已经是TagView 【参考方案1】:

我目前的解决方案是在同一个项目中创建一个动态框架目标“ProxyFramework”。我使用 Cocoapods 添加了“FrameworkB”依赖项并声明了一个与“FrameworkA”中声明的扩展方法不冲突的新属性:

public extension TagList 
    public dynamic var cornerRadius_: CGFloat 
        get  return cornerRadius 
        set  cornerRadius = newValue 
    

在我的应用程序目标中,我将新创建的框架目标添加到“Target Dependencies”,因此我现在可以通过此代理框架使用“FrameworkB”属性:

let view = UIView()
view.cornerRadius = 10    // FrameworkA: Ok

let tagView = TagView(title: "")
tagView.cornerRadius_ = 10    // ProxyFramework -> FrameworkB: Ok
(tagView as UIView).cornerRadius = 10    // FrameworkA: Ok

我希望看到更清洁的解决方案。

【讨论】:

【参考方案2】:

如果您在不相关的地方使用这些不同的类,也许您可​​以只在实际需要它们的源文件中导入特定符号。

 import class FrameworkA.TagView

【讨论】:

以上是关于Swift 中的扩展属性冲突子类声明的主要内容,如果未能解决你的问题,请参考以下文章

swift3.0 扩展协议

覆盖 Swift 扩展中的方法

Swift中的结构体,类,协议,扩展和闭包的用法以及? 和 !的区别

了解协议扩展中的 Swift 默认值属性

协议扩展中的 Swift 属性观察器?

是否可以通过扩展中的 Swift 4 KeyPaths 在 UIView 上设置属性?