我想创建一个Swift协议,可以应用于UILabel
、UITextField
和UITextView
,并且包含它们的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
的协议。
另外,UILabel
和 UITextField
的 text
和 attributedText
属性是可选的(String?
),而这些属性对于 UITextView
来说则是隐式解包的可选项(String!
)。所以对于这三个属性来说,使用的可选项和隐式解包的可选项并不一致。
因此,我不得不在协议中将 font
重命名为例如 uiFont
,并在上述每个扩展中实现以下别名 font
:
extension UILabel: MyProtocol {
var uiFont: UIFont? {
get { font }
set { font = newValue }
}
}
// … and similarly for UITextField and UITextView
这有点令人恼火,因为它减少了协议的简洁性。
我在Swift论坛上发现了这篇帖子,似乎是同样的问题,讨论似乎表示Swift 4.2不应该这样行事,但我正在使用Swift 5,仍然遇到这个问题。甚至有一个提案废除IUOs已经被合并。
请注意,我正在macOS Catalina 10.15.6 (19G2021)上使用Xcode 11.7和iOS 13.7。
有没有办法完全避免这个问题,或者使代码更加简洁,以便我不需要有那么多冗余代码呢?
谢谢