无法识别的选择器发送到实例 - Swift 仅 4

unrecognized selector sent to instance - Swift 4 only

我无法理解此错误的含义。在我迁移到 Swift 4 之前,我的应用程序运行良好。现在我在尝试打开我的几个视图控制器时遇到此 tableView:numberOfRowsInSection 错误。我在 Swift 3.2 中没有遇到任何这些错误。 numberOfRowsInSection 方法已在所有情况下实现,并且看起来很好。谁能指出我正确的方向?

2017-11-26 10:21:04.973523-0600 Y2GOsp[27701:6382461] -[Y2GOsp.ClientDetailViewController tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x7fa51c89f000 2017-11-26 10:21:43.328635-0600 Y2GOsp[27701:6382461] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Y2GOsp.ClientDetailViewController tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x7fa51c89f000'

numberOfRowsInSection 实现:

示例 1:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1
}

示例 2:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return dayAppoints.count
}

@Hamish 在他的评论中指出了这个问题。您忘记将 UITableViewDataSource 添加到 class 声明中。因此,您的数据源方法未公开给 Objective-C.

我尝试将 @objc 添加到方法中的建议证实了这个问题。

这在 Swift 3 中起作用的原因是 class 派生自 NSObject 的所有方法(UIViewController 确实如此)都可用于 Objective-C.

在 Swift 4 (due to SE-0160) 中,有必要用 @objc 显式标记将通过选择器调用的函数,除非您要覆盖在base class,或者在这种情况下,如果函数满足 @objc 协议定义的要求。

我遇到了同样的问题,我遵循了 vacawama 的建议。但是我没有在每个委托方法之前添加 @objc(我发现 @objc 标签非常难看),而是让我的 ViewController 实现了 UITableViewDataSource 和 UITableViewDelegate 协议(我有一个包含 UITableView 的通用 VC)和将我的 ViewController 作为数据源和委托明确分配给他的 tableView:

self.tableView.delegate = self
self.tableView.dataSource = self

它就像一个魅力,没有丑陋的@objc 标签。 事实上,我最初使用 InterfaceBuilder(通过 ctrl + 单击)将委托和数据源分配给 tableView