用于扩展非泛型类型的尾随 where 子句
Posted
技术标签:
【中文标题】用于扩展非泛型类型的尾随 where 子句【英文标题】:Trailing where clause for extension of non-generic type 【发布时间】:2016-03-23 08:52:30 【问题描述】:我有以下代码:
func registerNotification(name:String, selector:Selector)
NSNotificationCenter.defaultCenter().addObserver(self, selector: selector, name: name, object: nil)
func registerKeyboardNotifications()
let isInPopover = navigationController?.popoverPresentationController != nil
let ignore = isInPopover && DEVICE_IS_IPAD
if !ignore
registerNotification(UIKeyboardWillShowNotification, selector: Selector("keyboardWillShow:"))
registerNotification(UIKeyboardWillHideNotification, selector: Selector("keyboardWillHide:"))
在UIViewController
的扩展中。许多视图控制器重用此代码来注册键盘通知。然而,对于 Swift 2.2,它会产生一个警告。我喜欢新的#selector
语法,但不确定在这种情况下如何实现它。
我认为正确的解决方案是制定一个协议并扩展UIViewController
仅适用于符合该协议的实例。到目前为止我的代码:
@objc protocol KeyboardNotificationDelegate
func keyboardWillShow(notification: NSNotification)
func keyboardWillHide(notification: NSNotification)
extension UIViewController where Self: KeyboardNotificationDelegate
func registerKeyboardNotifications()
let isInPopover = navigationController?.popoverPresentationController != nil
let ignore = isInPopover && DEVICE_IS_IPAD
if !ignore
registerNotification(UIKeyboardWillShowNotification, selector: #selector(KeyboardNotificationDelegate.keyboardWillShow(_:)))
registerNotification(UIKeyboardWillHideNotification, selector: #selector(KeyboardNotificationDelegate.keyboardWillHide(_:)))
但是这让我出错了
trailing where clause for extension of non-generic type
在扩展行。有什么想法吗?
【问题讨论】:
【参考方案1】:解决方法很简单,在扩展子句中切换顺序:
extension UIViewController where Self: KeyboardNotificationDelegate
应该是
extension KeyboardNotificationDelegate where Self: UIViewController
【讨论】:
这对我帮助很大。我正在做相反的事情,extension UIViewController where Self: UICollectionViewDelegate
,但我没有意识到它需要与左侧的代表一起翻转。
感谢您提出这个问题!这有帮助!【参考方案2】:
extension Foo where ...
只能在Foo
为时使用
-
泛型类或结构:使用符合某些类型约束的泛型的默认实现进行扩展,
包含一些关联类型的协议,在关联类型符合某些类型约束时扩展了默认实现
当
Self
是特定(对象/引用)类型或符合某种类型约束时,我们使用默认实现扩展协议。
例如
// 1
class Foo<T>
extension Foo where T: IntegerType
struct Foz<T>
extension Foz where T: IntegerType
// 2
protocol Bar
associatedtype T
extension Bar where T: IntegerType
// 3
protocol Baz
extension Baz where Self: IntegerType
class Bax<T>: Baz
extension Baz where Self: Bax<Int>
func foo() print("foo")
let a = Bax<Int>()
a.foo() // foo
在您的情况下,UIViewController
是一个非泛型类类型,不符合上述任何一种。
正如您在自己的答案中所写,解决方案是针对 Self: UIViewController
的情况使用默认实现扩展您的委托协议,而不是尝试扩展 UIViewController
。
【讨论】:
以上是关于用于扩展非泛型类型的尾随 where 子句的主要内容,如果未能解决你的问题,请参考以下文章