【发布时间】:2018-03-02 07:41:15
【问题描述】:
尝试创建具有关联类型的通用协议。
当我尝试从委托访问方法时出现错误:
Cannot invoke 'numberOfSections' with an argument list of type '(containerView: UITableView)'
代码:
protocol ViewDelegate: class {
associatedtype ContainerView
associatedtype Model
func numberOfSections(containerView: ContainerView)
func aMethodThatTakesNoArugments()
}
class ViewController: UIViewController {
var newView = AnyView<ViewController>()
override func viewDidLoad() {
super.viewDidLoad()
newView.delegate = self
}
}
extension ViewController: ViewDelegate {
typealias ContainerView = UITableView
typealias Model = Int
func numberOfSections(containerView: ContainerView) {
// do something with containerView
}
func aMethodThatTakesNoArugments() {}
}
class AnyView<Delegate: ViewDelegate>: UIView {
weak var delegate: Delegate?
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func getData() {
delegate?.aMethodThatTakesNoArugments() // This compiles fine
delegate?.numberOfSections(containerView: UITableView()) // Get a compiler error on this line (I am passing an argument):
// Cannot invoke 'numberOfSections' with an argument list of type '(containerView: UITableView)'
}
}
我觉得我错过了什么。不带参数的方法编译得很好;但是,如果我调用一个带有参数的方法,我会得到一个编译错误。
【问题讨论】:
-
我不明白你在尝试什么。您的
ViewDelegate没有定义numberOfSections。为什么你认为你可以调用它? -
对不起。我试图进一步简化并犯了一个错误。固定。
-
我明白了。我没有时间写答案,但是当您将类声明为
AnyView<Delegate: ViewDelegate>时,Delegate可能是符合ViewDelegate的任何类型。它的关联类型可能不是UITableView。为泛型参数Delegate添加约束。 -
谢谢。对不起,能不能详细点。你的意思是使用
where子句吗?但是我应该在哪里添加呢? -
只是一个快速的设计要点,看起来您正在尝试使用类型擦除将某种
UITableView功能填充到普通的UIView中。如果那是您的目标,我强烈建议您转向另一个方向并制作 UIView 的专门 子类,而不是尝试建立更通用的 View 和 Delegate 连接,以应对看似特殊的情况。
标签: swift xcode generics swift4