快速覆盖文件私有扩展名中的打开变量时发出警告
Posted
技术标签:
【中文标题】快速覆盖文件私有扩展名中的打开变量时发出警告【英文标题】:Warning when Overriding an open var inside a fileprivate extension in swift 【发布时间】:2017-01-18 16:03:01 【问题描述】:考虑以下问题。
fileprivate extension UIButton
override open var isSelected: Bool
didSet
self.titleLabel?.font = isSelected ? UIFont(name: "HelveticaNeue-Medium", size: 14) : UIFont(name: "HelveticaNeue-Light", size: 14)
过了一会儿,xcode 中出现了一个警告,要求我将“open”更改为 fileprivate。当然,如果我这样做,那么我不会从 UIButton 覆盖相同的 isSelected
变量,我会收到错误消息。
这是一个 XCode 错误吗?我无法将扩展设置为公开或内部的,因为该行为会改变应用程序中的所有 UIButtons
。
有什么想法吗?
更新:
确切的警告是这样的。
【问题讨论】:
你得到的确切警告是什么? 声明完全有效并且按预期工作。警告是错误的。 警告消息是错误的,因为编译器的消息文件中存在错误,它应该是“在文件私有扩展中声明 OPEN var”,类似问题请参见 ***.com/questions/40983010/…。作为解决方案,您可以从extension
中删除 fileprivate
。
【参考方案1】:
有趣的是,Swift 实际上允许你这样做。我相信你不能在私有(fileprivate)上下文中覆盖公共方法是故意的。
你真正想要的东西模棱两可:
在您的情况下,您在仅适用于文件本身的上下文中覆盖该方法。有人可能认为覆盖仅适用于该文件中的按钮,但事实并非如此。现在,您的应用程序中的每个按钮实际上都将具有覆盖的方法(已对其进行测试)。因此,您的解决方案肯定是在公开的扩展中覆盖此方法。
注意:我知道它是一个属性而不是一个方法,但在幕后,这是一个在调用对象的 setter 后触发的方法。
【讨论】:
我的心都碎了。它确实无处不在!那为什么还存在 fileprivate 扩展呢? @L_Sonic 不用于覆盖。它用于子类化或创建文件私有类。甚至对于公共协议实现也不行。在您的情况下使用子类。另外让我与您分享一个您很少看到的建议:当涉及到对不属于您的类(例如 UIButton)进行扩展时,不惜一切代价避免!说真的,除非真的没有其他方法可以产生您的解决方案,否则永远不要这样做。 似乎比为了更改字体而对整个类进行子类化更简洁。感谢您的建议! @L_Sonic 我能感觉到你,但不幸的是,这些事情不是那样工作的。但是,如果他们确实只是问自己一件事:扩展什么时候才能真正起作用?如果按钮是在这个文件中创建的?如果在此文件中调用了 setter?如果此文件中使用了按钮实例?一般来说,我练习拥有一个按钮的自定义子类,然后在整个应用程序中使用它。然后,您可以轻松添加其他属性或逻辑。您甚至可以添加 IB 检查项以在 IB 中控制它们。以上是关于快速覆盖文件私有扩展名中的打开变量时发出警告的主要内容,如果未能解决你的问题,请参考以下文章