泛型类不会将委托调用转发给具体的子类

编程入门 行业动态 更新时间:2024-10-26 08:33:52
本文介绍了泛型类不会将委托调用转发给具体的子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

给出以下内容.

protocol EntityType { var displayString: String { get } } extension String: EntityType { var displayString: String { return self } } class GenericListViewController<Entity>: UIViewController, UITableViewDataSource, UITableViewDelegate where Entity: EntityType { let items: [Entity] let tableView: UITableView init(items: [Entity]) { self.items = items self.tableView = UITableView() super.init(nibName: nil, bundle: nil) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func loadView() { super.loadView() tableView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(tableView) NSLayoutConstraint.activate([ tableView.topAnchor.constraint(equalTo: view.topAnchor), tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor) ]) tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell") tableView.dataSource = self tableView.delegate = self } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return items.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) cell.textLabel?.text = items[indexPath.row].displayString return cell } // func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // // } } class StringListViewController: GenericListViewController<String> { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { print("selected: \(items[indexPath.row])") } }

为什么在具体的子类中不调用tableView:didSelectRowAt:?对于非泛型类型或父类具有实现并且子类覆盖它的情况,这可以很好地工作.这是预期的行为,Swift错误还是我遗漏了一些东西?

Why isn't tableView:didSelectRowAt: being called in the concrete subclass? This works fine for non-generic types or when the parent class has an implementation and the sub-class overrides it. Is this expected behavior, Swift bug or am I missing something?

推荐答案

这似乎是一个可能的错误.我猜想这可能与Swift泛型对Objective-C运行时不可见有关,因此即使调用直接在GenericListViewController<Entity>中实现的方法,Swift之间也可能会出现一些错误行为和Obj-C运行时试图找出覆盖.绝对值得一个错误报告.

It does seem like a possible bug. My guess it that it might have something to do with the fact that Swift generics are not visible to the Objective-C runtime, so even though your methods implemented directly in GenericListViewController<Entity> are being called, there may be some buggy behavior between the Swift and Obj-C runtimes trying to figure out overrides. Definitely worth a bug report.

我会注意到,在严格的OOP中,抽象超类通常不符合协议本身,它们只是提供默认的实现.声明协议一致性并填写任何缺少的实现仍取决于具体的子类.

I will note though, that in strict OOP abstract superclasses generally do not conform to protocols themselves, they simply provide default implementations. It's still up to the concrete subclasses to declare protocol conformance and fill in any missing implementations.

对于上面的代码,您的GenericListViewController<Entity>类不应符合UITableViewDataSource或UITableViewDelegate.它只是提供了默认方法实现,该默认方法实现将允许具体的子类遵循而不必重写那些方法实现(除非需要重写).您的StringListViewController应该是声明符合这两个协议的一个.如果您修改代码来执行此操作,则它实际上将按预期工作.

In the case of your code above, your GenericListViewController<Entity> class should not conform to UITableViewDataSource or UITableViewDelegate. It simply provides the default method implementations that would allow a concrete subclass to conform without having to rewrite those method implementations (unless override is desired). Your StringListViewController should be the one declaring conformance to the two protocols. If you modify your code to do that, it will actually work as expected.

这不会改变您可能已经在Swift/Obj-C interop中发现一个错误的事实.我相信您目前应该工作正常,尽管这不是处理协议一致性的严格OOP方法.

This doesn't change the fact that you have probably discovered a bug in Swift / Obj-C interop, though. I believe that what you have currently should work, although it's not the strict OOP way of handling protocol conformance.

更多推荐

泛型类不会将委托调用转发给具体的子类

本文发布于:2023-11-12 09:43:17,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1581149.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:子类   会将   转发给   泛型类不

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!