在 Swift 中覆盖超类委托
Overriding a superclass delegate in Swift
我正在开发一个包含两个 UIView 的 Swift (v1.2) 项目。 MyView 和 MyViewSubclass 。
MyView 有一个委托,我想在 MyViewSubclass 中将其覆盖为子协议,类似于 UITableViews 有一个 UITableViewDelegate 也符合超级 UIScrollViewDelegate.
我的第一个想法是覆盖超类 属性,但这 会导致编译器错误 ,因为子类无法覆盖超类 属性使用不同的类型。
// Example throws a compiler error. Can't override property with different type
class MyView : UIView {
weak var delegate : MyViewDelegate?
}
class MyViewSubclass : MyView {
override weak var delegate : MyViewSubclassDelegate? // Compiler error
}
protocol MyViewDelegate {
func someFunc ()
}
protocol MyViewSubclassDelegate : MyViewDelegate {
//func someFunc () Edit: redefinition not necessary, thanks @Rob!
func someOtherFunc ()
}
我的第二个想法是覆盖委托 属性 的隐式 getter 和 setter 方法。子类可以有一个 getter,它采用 MyViewSubclassDelegate,并向下转换为 MyViewDelegate 协议,因此 属性本身不需要被覆盖。
此方法也会导致编译器错误。访问器实际上不能 "override" 超类方法,因为它们具有不同的方法签名,并且不能只是声明,因为它们的名称与超类冲突 setters.
// Example throws a compiler error. Can't declare function with a conflicting name
class MyViewSubclass : MyView {
func setDelegate ( newValue : MyViewSubclassDelegate ) { // Compiler error
super.delegate = newValue as? MyViewDelegate
}
func getDelegate () -> MyViewSubclassDelegate { // Compiler error
return super.delegate as? MyViewSubclassDelegate
}
}
我可以让子类覆盖超类的 getter 和 setter,然后将委托存储在单独的子类中 属性, 这确实有效,但是子类看起来应该分配一个 MyViewDelegate,而实际上它需要分配一个 MyViewSubclassDelegate,这可能会在未来造成严重的混乱。
// Example works, but it is unclear that MyViewSubclass's delegate should be
// assigned a MyViewSubclassDelegate
class MyViewSubclass : MyView {
private weak var _subclassDelegate : MyViewSubclassDelegate?
override weak var delegate : MyViewDelegate? { // Ambiguous type
didSet {
_subclassDelegate = delegate as? MyViewSubclassDelegate
}
}
}
我知道至少类似的东西是可能的,因为 类 像 UITableView 和 UICollectionView 似乎做我想做的,但它们也是用 Objective-C 而不是 Swift 写的, 因此语言允许的细节可能不同。
有没有办法让 Swift 子类用子类型覆盖超类的 属性?
这并不理想,但如果一个协议是从另一个协议继承的,而不是使用不同的类型,使用相同的类型,但在 didSet
:
中实现验证
class MyView : UIView {
/// The `MyViewDelegate` delegate
weak var delegate: MyViewDelegate?
}
class MyViewSubclass: MyView {
/// The `MyViewSubclassDelegate` delegate.
///
/// **Note: This must be MyViewSubclassDelegate**
override weak var delegate: MyViewDelegate? {
didSet {
assert(delegate == nil || delegate is MyViewSubclassDelegate, "The delegate of MyViewSubclass must be of type `MyViewSubclassDelegate`")
}
}
}
这很不雅观,但至少您会立即得到一个运行时错误,从而引起程序员的注意。通过包含 ///
注释,它也将显示在快速帮助中。
--
或者,您可以采取更彻底的改变,例如类似于 ABPeoplePickerNavigationController
的 delegate
和 peoplePickerDelegate
属性,其中子类委托是通过不同的 属性.
指定的
我正在开发一个包含两个 UIView 的 Swift (v1.2) 项目。 MyView 和 MyViewSubclass 。
MyView 有一个委托,我想在 MyViewSubclass 中将其覆盖为子协议,类似于 UITableViews 有一个 UITableViewDelegate 也符合超级 UIScrollViewDelegate.
我的第一个想法是覆盖超类 属性,但这 会导致编译器错误 ,因为子类无法覆盖超类 属性使用不同的类型。
// Example throws a compiler error. Can't override property with different type
class MyView : UIView {
weak var delegate : MyViewDelegate?
}
class MyViewSubclass : MyView {
override weak var delegate : MyViewSubclassDelegate? // Compiler error
}
protocol MyViewDelegate {
func someFunc ()
}
protocol MyViewSubclassDelegate : MyViewDelegate {
//func someFunc () Edit: redefinition not necessary, thanks @Rob!
func someOtherFunc ()
}
我的第二个想法是覆盖委托 属性 的隐式 getter 和 setter 方法。子类可以有一个 getter,它采用 MyViewSubclassDelegate,并向下转换为 MyViewDelegate 协议,因此 属性本身不需要被覆盖。
此方法也会导致编译器错误。访问器实际上不能 "override" 超类方法,因为它们具有不同的方法签名,并且不能只是声明,因为它们的名称与超类冲突 setters.
// Example throws a compiler error. Can't declare function with a conflicting name
class MyViewSubclass : MyView {
func setDelegate ( newValue : MyViewSubclassDelegate ) { // Compiler error
super.delegate = newValue as? MyViewDelegate
}
func getDelegate () -> MyViewSubclassDelegate { // Compiler error
return super.delegate as? MyViewSubclassDelegate
}
}
我可以让子类覆盖超类的 getter 和 setter,然后将委托存储在单独的子类中 属性, 这确实有效,但是子类看起来应该分配一个 MyViewDelegate,而实际上它需要分配一个 MyViewSubclassDelegate,这可能会在未来造成严重的混乱。
// Example works, but it is unclear that MyViewSubclass's delegate should be
// assigned a MyViewSubclassDelegate
class MyViewSubclass : MyView {
private weak var _subclassDelegate : MyViewSubclassDelegate?
override weak var delegate : MyViewDelegate? { // Ambiguous type
didSet {
_subclassDelegate = delegate as? MyViewSubclassDelegate
}
}
}
我知道至少类似的东西是可能的,因为 类 像 UITableView 和 UICollectionView 似乎做我想做的,但它们也是用 Objective-C 而不是 Swift 写的, 因此语言允许的细节可能不同。
有没有办法让 Swift 子类用子类型覆盖超类的 属性?
这并不理想,但如果一个协议是从另一个协议继承的,而不是使用不同的类型,使用相同的类型,但在 didSet
:
class MyView : UIView {
/// The `MyViewDelegate` delegate
weak var delegate: MyViewDelegate?
}
class MyViewSubclass: MyView {
/// The `MyViewSubclassDelegate` delegate.
///
/// **Note: This must be MyViewSubclassDelegate**
override weak var delegate: MyViewDelegate? {
didSet {
assert(delegate == nil || delegate is MyViewSubclassDelegate, "The delegate of MyViewSubclass must be of type `MyViewSubclassDelegate`")
}
}
}
这很不雅观,但至少您会立即得到一个运行时错误,从而引起程序员的注意。通过包含 ///
注释,它也将显示在快速帮助中。
--
或者,您可以采取更彻底的改变,例如类似于 ABPeoplePickerNavigationController
的 delegate
和 peoplePickerDelegate
属性,其中子类委托是通过不同的 属性.