【发布时间】:2020-09-03 23:10:07
【问题描述】:
我正在尝试制作一个可以在 UILabel、UITextField 和 UITextView 上使用的 Swift 协议,其中包含它们的 text、attributedText 和 font 属性。
然而,不幸的是,这三个类与它们是使用这些属性的可选类型还是隐式展开的可选类型不一致。
例如,如果我创建这个协议:
protocol MyProtocol: class {
var font: UIFont? { get set }
}
我应用它:
extension UILabel: MyProtocol { }
extension UITextField: MyProtocol { }
extension UITextView: MyProtocol { }
它对UITextField 和UITextView 工作正常,但UILabel 的font 属性是UIFont!,所以编译器说UILabel 不符合MyProtocol。
另外,text 和 attributedText 对于 UILabel 和 UITextField 是可选的 (String?),但对于 UITextView (String!) 是隐式展开的。因此,对于所有三个属性,哪些使用可选项以及哪些使用隐式展开的选项甚至都不一致。
所以我不得不将协议中的font 重命名为例如。 uiFont 本质上是 font 的别名,在上面的每个扩展中都有以下实现:
extension UILabel: MyProtocol {
var uiFont: UIFont? {
get { font }
set { font = newValue }
}
}
// … and similarly for UITextField and UITextView
这有点烦人,因为它破坏了协议的简单性。
我发现this post on the Swift forum 似乎是同一个问题,讨论似乎说这不是它在 Swift 4.2 中应该表现的方式,但我正在使用 Swift 5 并且仍然得到这个。甚至还有一个proposal to abolish IUOs 得到了merged。
请注意,我在 macOS Catalina 10.15.6 (19G2021) 上使用 Xcode 11.7 和 iOS 13.7。
有什么方法可以完全避免这个问题,或者让代码更简洁一些,这样我就不需要那么多冗余了?
谢谢
【问题讨论】:
-
优秀的总结。我建议提交一个错误。我们总是被告知隐式展开的 Optional 只是“是”一个 Optional 那么为什么它会像这样妨碍你呢? (而且为什么 API 中还剩下任何 IUO?
-
猜猜这不是一个真正的错误(请参阅上面 swift.org 上的错误)。
标签: ios swift uilabel swift-protocols swift-optionals