在Swift中修改(精细化)委托类型

3

我有一个类(Swift)其中含有指向委托的弱引用,如下所示:

import UIKit


@objc public protocol DRSlidingPanelViewControllerDelegate : class {

    optional func didSlidePanel(panelHidden : Bool , sender : DRSlidingPanelViewController) -> Void

} 

public class DRSlidingPanelViewController: UIViewController {

    public weak var delegate : DRSlidingPanelViewControllerDelegate?

///other stuff...
}

现在我创建了一个继承第一个协议的另一个协议的子类,我想修改继承的“delegate”属性。

@objc public protocol  DRTableViewControllerDelegate : DRSlidingPanelViewControllerDelegate  {

    optional func someFunction(sender : DRTableViewController) -> Void
}


public class DRTableViewController: DRSlidingPanelViewController {

 //  public weak var delegate : DRTableViewControllerDelegate?
}

在子类中重新声明委托(delegate)属性给我加了3个错误,如果我取消注释,则会出现以下错误:

  1. 类型为'DRTableViewControllerDelegate?'(又名'Optional')的属性'delegate'无法覆盖具有类型为'DRSlidingPanelViewControllerDelegate?'(又名'Optional')的属性
  2. 具有Objective-C选择器'delegate'的getter与来自超类'DRSlidingPanelViewController'具有相同Objective-C选择器的getter 'delegate'发生冲突
  3. 具有Objective-C选择器'setDelegate:'的setter与来自超类'DRSlidingPanelViewController'带有相同Objective-C选择器的setter 'delegate'发生冲突

现在我理解这些错误的本质,并且它们是尝试更改委托指针上的“类型”的不同方面。任何人可以给我一个提示如何做到这一点吗?显然可以做到,看看UITableView如何更改从UIScrollView继承的委托指针即可。在objC中,我会得到一个警告,可以用@dynamic消除该警告。 感谢和最好的问候

编辑/添加 谢谢Matt,我看到这个之前的问题,但很遗憾,它已经关闭,而且我个人不会接受它作为最终答案,因为这是一种妥协。

如果我在xCode中右键单击UITableView并“跳转到定义”,我会看到以下内容

@available(iOS 2.0, *)
public class UITableView : UIScrollView, NSCoding {

    public init(frame: CGRect, style: UITableViewStyle) // must specify style at creation. -initWithFrame: calls this with UITableViewStylePlain
    public init?(coder aDecoder: NSCoder)

    public var style: UITableViewStyle { get }
    weak public var dataSource: UITableViewDataSource?
    **weak public var delegate: UITableViewDelegate?**

//plenty other stuff..
}

所以我恭敬地建议,肯定有一种方法可以做到这一点。

1
在这里已经很详细地讨论了:https://dev59.com/4Y3da4cB1Zd3GeqP4sgR 这绝对是一个问题! - matt
1
这里也有一个有趣的讨论:https://dev59.com/mGAf5IYBdhLWcg3w9mts - matt
1
是的,但底层代码是用Objective-C编写的。你只是在看一个Swift API翻译。所以我想说,你实际上不能用Swift来做这件事。我很希望我是错的,但我不认为我错了... - matt
1个回答

3
我认为目前你不能这样做。这至少令人失望。你只需在子类中将委托变量命名为其他名称。
所以,这是合法的,但当然完全无法满足您的要求:
@objc protocol P1 {
}
@objc protocol P2 : P1 {
}
public class VC1: UIViewController {
    weak var delegate : P1?
}
public class VC2: VC1 {
    weak var delegate2 : P2?
}

如果您真的不喜欢存储器的繁殖,您可以将delegate2设置为计算变量,访问继承的delegate即可。
@objc protocol P1 {
}
@objc protocol P2 : P1 {
}
public class VC1: UIViewController {
    weak var delegate : P1?
}
public class VC2: VC1 {
    weak var delegate2 : P2? {
        set {
            super.delegate = newValue
        }
        get {
            return super.delegate as? P2
        }
    }
}

我非常感谢你的建议,但我会给你一个+1而不是接受,因为我知道还有其他方法。我仍然是你的粉丝,祝一切顺利。 - Jef
我看到另一个妥协方案,我可以将我的DRTableViewControllerDelegate协议更改为DRSlidingPanelViewControllerDelegate的扩展,但我认为这将强制我仅使用可选函数。 - Jef
1
你完全正确不接受!这是个坏消息。 - matt
1
但我不相信有什么办法;看看我给你的链接。看起来我们已经走过这条路了。 :( 请查看我的修订答案;它并没有更好,但有点可爱。 - matt
我确实喜欢这个想法,并且也在考虑类似的方法 - 但是私有和只读,只是一个getter,可以有条件地将现有的委托指针转换类型。谢谢,伙计。 - Jef
我想看看你能做出什么!谢谢 - matt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接