带有 Swift 5.0 编译器的 Xcode 10.2 - 协议继承问题
Posted
技术标签:
【中文标题】带有 Swift 5.0 编译器的 Xcode 10.2 - 协议继承问题【英文标题】:Xcode 10.2 with Swift 5.0 compiler - protocol inheritance issue 【发布时间】:2019-04-09 11:58:26 【问题描述】:当前的 Xcode 版本 (10.2) 存在一个大问题。
有一个带有以下签名的BasicViewController
类:
class BasicViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
然后我们有另一个像ExampleViewController: BasicViewController
这样的类,它有一些额外的逻辑。
现在是棘手的部分......
我们在不同的模拟器和设备上构建和运行应用程序,一切正常。然后我们归档应用程序,突然didSelectRow
不再被解雇。项目的深度清理和清理使我们能够重现问题而无需再次存档。
我想不出任何可能发生这种情况的情况。而且它变得更糟,因为我发现了更多类似的问题,UITableViewDelegate
方法仅在运行归档应用程序时才在子类中调用。归档和提交应用期间的某些优化是否存在问题?
我确认我们正确设置了桌子的dataSource
和delegate
,桌子上没有手势识别器。同样的逻辑在第二次/第三次运行应用程序后运行良好,但在深度清理项目后第一次失败。
我们进行了测试并在子类中设置了UITableViewDataSource
和UITableViewDelegate
,然后每次都按预期工作。似乎继承协议并不能很好地工作。如果我们将协议保留在父类中,并将它们添加到子类中,那么它说子类中的协议是多余的。
有没有人经历过类似的事情?欢迎提出任何建议。
【问题讨论】:
那么您对协议继承或 didSelectRow 函数有问题吗? @nTri,没有触发 didSelectRow,正如我在测试中所描述的,它似乎与父类中的 didSelectRow (UITableViewDelegate) 协议有关。正如我所描述的,这是一种非常奇怪的行为,所以我试图将我所有的想法和测试都放在描述中。 相同的代码在 Xcode 10.1 中是否仍然有效?您应该尝试创建一个测试项目,看看在该项目中使用 Xcode 10.2 是否也会出现同样的问题。 @DávidPásztor,似乎与 Xcode 10.2 明确相关。 我们遇到了一个看起来非常非常相似的问题——但不确定它是否完全相同。我们在这里发了一个帖子:***.com/questions/56009500/… 【参考方案1】:您可能会在 Swift 5.0 编译器中遇到https://bugs.swift.org/browse/SR-10257。如果您至少有三个文件,就会发生这种情况:
BasicViewController.swift
SomeOtherFile.swift
ExampleViewController.swift
如果SomeOtherFile.swift
对AnyObject
类型的值进行任何调用,则您将在wholemodule
模式下编译,并且文件按上述顺序传递给编译器(SomeOtherFile.swift
在中间两个),那么编译器似乎无法正确推断@objc
-ness 以实现func tableView(_:, didSelectRowAt:)
。您现在可以通过使用@objc
明确标记它来解决它。
【讨论】:
与其将其标记为@objc
,不如关闭wholemodule
优化更容易?
是的,您可以这样做,但关闭 wholemodule
可能会影响性能。您也可以通过从 Xcode 目标中删除 Basic
和 Example
然后再次添加它们来解决它,这将导致它们以不同的顺序传递给编译器。
我看到同样的问题通过CBPeripheralDelegate
迁移到 10.2。添加显式 @objc
解决了该问题。它没有正确解析其中一种可选方法。
有趣的错误(或功能:P)...奇怪的是它具有优先级中等,因为这会破坏很多应用程序
我添加了@objc,但它仍然不起作用,任何人都可以帮助我。【参考方案2】:
我遇到了同样的问题。我通过直接在我的主类中添加方法来修复它,并在其他类中覆盖它们。现在一切都被正确调用了。
【讨论】:
【参考方案3】:您应该使用Storyboard
和Class 附加dataSource
和delegate
双方,因为一旦我对tableview 有同样的问题,这是由于在课堂上我没有完成
self.tableView.delegate = self
self.tableView.datasource = self
我认为你没有这样做。
我知道没有必要同时使用这两种风格,但有时我们需要它。看看这个答案https://***.com/a/39443079/3485420
【讨论】:
以上是关于带有 Swift 5.0 编译器的 Xcode 10.2 - 协议继承问题的主要内容,如果未能解决你的问题,请参考以下文章
带有 iOS 5.0 的 Xcode 4.2 未检测到 iPhone iOS 5.1.1
不能在带有 Xcode 11 包管理器的 Swift 包中包含 C 文件
使用 Swift 4.0 编译的模块无法在 Swift 3.1 中导入框架二进制文件
在 Xcode 5 上使用 Boost - Apple LLVM 5.0