在 Swift 中委托不同类型的属性

Posted

技术标签:

【中文标题】在 Swift 中委托不同类型的属性【英文标题】:Delegate property with different type in Swift 【发布时间】:2015-07-29 15:14:12 【问题描述】:

好的,所以我们有 UIScrollView 声明:

protocol UIScrollViewDelegate: NSObjectProtocol  ... 
class UIScrollView: UIView 
    ...
    weak var delegate: UIScrollViewDelegate?
    ...

然后UITableViewdelegate 变体?

protocol UITableViewDelegate: NSObjectProtocol, UIScrollViewDelegate  ... 
class UITableView: UIScrollView 
    ...
    weak var delegate: UITableViewDelegate?
    ...

Apple 是如何做到的?当我做我的时候

protocol MyScrollViewSubclassDelegate: NSObjectProtocol, UIScrollViewDelegate  ... 
class MyScrollViewSubclass: UIScrollView 
    ...
    weak var delegate: MyScrollViewSubclassDelegate?
    ...

我得到属性'delegate',类型为'MyScrollViewSubclassDelegate?'无法覆盖类型为“UIScrollViewDelegate?”的属性。

【问题讨论】:

如果将子类设置为 UITableView。 class MyScrollViewSubclass: UITableView 你在 Swift 2.0 中尝试过协议扩展吗? 我的问题是苹果如何做到这一点“魔法”,而不是如何设计“解决方法”。 【参考方案1】:

我偶然发现了几次,我发现的唯一解决方法就是将我的属性称为其他名称,例如 customDelegate 或您喜欢的任何名称。

能够将其称为委托确实很好,但是嘿!

【讨论】:

这里也一样。但是......今天我意识到苹果做到了。我真的很好奇怎么做! 你试过unowned(unsafe) var delegate: MyScrollViewSubclassDelegate? 吗?这是我在 UITableView 源码中看到的。 我在那里看到weak。要么unowned不能应用于非类类型MyScrollViewSubclassDelegate?【参考方案2】:

MyScrollViewSubclass 具有 UIScrollView 的委托属性,因为它是 UIScrollView 的子类。

由于delegate已经被UIScrollView定义了,你不能用新的类型定义相同的属性名。

将变量名 delegate 更改为 myDelegate(或其他名称),它应该可以工作。

【讨论】:

这就是我解决问题所需的全部内容。【参考方案3】:

我得到了这个工作,但我不太喜欢这个解决方案,因为它抛弃了类型检查。

我做的是这个。在我的基类中,我将委托声明为

weak var delegate: AnyObject? = nil

然后,当我想在委托上调用方法时,我会这样做

if let delegate = self.delegate as? MyBaseClassProtocol  delegate.myMethod() 

在我的子类中,我也可以做同样的事情

if let delegate = self.delegate as MySubclassProtocol  delegate.mySubclassMethod() 

正如我所说,它有效,但我不太喜欢它。在我看来,不要轻易放弃类型检查。我只是分享希望有更强大的 Swift 技能的人可以改进它,或者纠正它。

【讨论】:

以上是关于在 Swift 中委托不同类型的属性的主要内容,如果未能解决你的问题,请参考以下文章

接口生成器、@IBOutlet 以及 Swift 中委托和数据源的协议

c#中委托的作用是啥?

C#中委托如何使用?

kotlin中委托的概念和原理

C#中委托和事件的区别

c#中委托怎么用