子 class 中的委托方法有时不会被 Swift 5 编译器调用
Delegate methods in child class sometimes not called with Swift 5 compiler
编辑: 作为 sunshinejr pointed out ,这已得到修复,将与下一个 Xcode/Swift 版本一起发布。
在将 Xcode 10.1 更新到 Xcode 10.2 后,我看到了很多奇怪的行为,包括 Swift 4 和 Swift 5 代码库。
其中一个问题是 ViewController 不再调用 ScrollView 委托方法。简化视图层级如下:
| ScrollView (ParentScrollView)
| -- Stack View
| ---- ScrollView (ChildScrollView)
| ---- ScrollView (ChildScrollView)
| ---- ScrollView (ChildScrollView)
它作为具有多个页面的视图:ParentScrollView
可以水平滚动,ChildScrollView
可以垂直滚动。
ViewController 是所有 Scrollviews 的委托(在 Storyboard 中设置),但是在滚动任何视图(ParentScrollView 或 ChildScrollView)时不会调用委托方法(如 scrollViewDidEndDecelerating
)。 ViewController
的基础class符合UIScrollViewDelegate
.
我试过在代码中设置委托,除此之外我不知道我可能做错了什么。转换没有更改 class 中的任何代码,但在更新之前一切正常。我在 Swift 5 Release Notes.
中也找不到一般的手势、委托或滚动视图的任何更改
这似乎是 Swift 5 编译器的错误。此外,它有时有效,有时无效 - 所有这些都无需更改任何代码或项目设置。
为什么这不再有效?有没有其他人经历过类似的行为?
由于所有 UIScrollViewDelegate
方法都是可选的,如果编译器认为您没有实现它们,您将永远不会看到编译器的错误,很可能发生的事情是 Apple 在 [=15] 中更改了方法签名=] 5(再次)并且由于某种原因迁移工具没有工作。
检查方法名称以及 UIScrollViewDelegate
更新到 USwift 5 文档,您会发现您的方法名称可能不同,只需更正它们,一切都应该再次工作。
编辑: 作为 sunshinejr pointed out ,这已得到修复,将与下一个 Xcode/Swift 版本一起发布。
我发现了问题,下面是重现问题的方法。
class A: UIViewController, UIScrollViewDelegate {
// ...does not implement 'scrollViewDidEndDecelerating'
}
class B: A {
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// Will not be called!
}
}
什么有效:
class A: UIViewController, UIScrollViewDelegate {
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// Probably empty
}
}
class B: A {
override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// Will be called!
}
}
如果基 class 没有实现委托方法,编译器似乎认为它没有实现。如果只有子class实现,它是找不到的。
我仍然无法解释为什么 Swift 5 会改变这种行为,但至少我找到了解决方案。也许有人可以提供进一步的见解?
我们 运行 使用 UITextViewDelegate
另一种解决方法是将 @objc
标记添加到超类中的方法
看起来这个问题在 2016 年也存在,并且在某一时刻得到了修复:https://bugs.swift.org/browse/SR-2919
正如 Jan 所指出的,这是一个 Swift 5 回归。 Swift 的 JIRA as well as on radar (rdar://problem/49482328). This is also already fixed (PR here) 对此进行了跟踪,但我们需要等待下一个 Xcode/Swift 版本。
编辑: 从 Xcode 10.3 开始,我们观察到错误已修复,但我们仍在监视它是否已永久修复。
升级到 Xcode 10.2 后,我仅在发布方案中遇到了同样的问题。我还测试了 Xcode 10.3,它的行为完全相同。
对于那些不想在委托实现中到处添加 @objc 的人。
快速解决方案是在构建设置中禁用 Swift 5 编译器优化:
对于已经升级到 Xcode 10.3 的人来说,这个构建设置选项似乎不再可见,但您仍然可以通过项目的 pbxproj 文件直接更改它,它应该出现在xcode UI 之后。
SWIFT_COMPILATION_MODE = singlefile;
编辑: 作为 sunshinejr pointed out
在将 Xcode 10.1 更新到 Xcode 10.2 后,我看到了很多奇怪的行为,包括 Swift 4 和 Swift 5 代码库。
其中一个问题是 ViewController 不再调用 ScrollView 委托方法。简化视图层级如下:
| ScrollView (ParentScrollView)
| -- Stack View
| ---- ScrollView (ChildScrollView)
| ---- ScrollView (ChildScrollView)
| ---- ScrollView (ChildScrollView)
它作为具有多个页面的视图:ParentScrollView
可以水平滚动,ChildScrollView
可以垂直滚动。
ViewController 是所有 Scrollviews 的委托(在 Storyboard 中设置),但是在滚动任何视图(ParentScrollView 或 ChildScrollView)时不会调用委托方法(如 scrollViewDidEndDecelerating
)。 ViewController
的基础class符合UIScrollViewDelegate
.
我试过在代码中设置委托,除此之外我不知道我可能做错了什么。转换没有更改 class 中的任何代码,但在更新之前一切正常。我在 Swift 5 Release Notes.
中也找不到一般的手势、委托或滚动视图的任何更改这似乎是 Swift 5 编译器的错误。此外,它有时有效,有时无效 - 所有这些都无需更改任何代码或项目设置。
为什么这不再有效?有没有其他人经历过类似的行为?
由于所有 UIScrollViewDelegate
方法都是可选的,如果编译器认为您没有实现它们,您将永远不会看到编译器的错误,很可能发生的事情是 Apple 在 [=15] 中更改了方法签名=] 5(再次)并且由于某种原因迁移工具没有工作。
检查方法名称以及 UIScrollViewDelegate
更新到 USwift 5 文档,您会发现您的方法名称可能不同,只需更正它们,一切都应该再次工作。
编辑: 作为 sunshinejr pointed out
我发现了问题,下面是重现问题的方法。
class A: UIViewController, UIScrollViewDelegate {
// ...does not implement 'scrollViewDidEndDecelerating'
}
class B: A {
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// Will not be called!
}
}
什么有效:
class A: UIViewController, UIScrollViewDelegate {
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// Probably empty
}
}
class B: A {
override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// Will be called!
}
}
如果基 class 没有实现委托方法,编译器似乎认为它没有实现。如果只有子class实现,它是找不到的。
我仍然无法解释为什么 Swift 5 会改变这种行为,但至少我找到了解决方案。也许有人可以提供进一步的见解?
我们 运行 使用 UITextViewDelegate
另一种解决方法是将 @objc
标记添加到超类中的方法
看起来这个问题在 2016 年也存在,并且在某一时刻得到了修复:https://bugs.swift.org/browse/SR-2919
正如 Jan 所指出的,这是一个 Swift 5 回归。 Swift 的 JIRA as well as on radar (rdar://problem/49482328). This is also already fixed (PR here) 对此进行了跟踪,但我们需要等待下一个 Xcode/Swift 版本。
编辑: 从 Xcode 10.3 开始,我们观察到错误已修复,但我们仍在监视它是否已永久修复。
升级到 Xcode 10.2 后,我仅在发布方案中遇到了同样的问题。我还测试了 Xcode 10.3,它的行为完全相同。
对于那些不想在委托实现中到处添加 @objc 的人。
快速解决方案是在构建设置中禁用 Swift 5 编译器优化:
对于已经升级到 Xcode 10.3 的人来说,这个构建设置选项似乎不再可见,但您仍然可以通过项目的 pbxproj 文件直接更改它,它应该出现在xcode UI 之后。
SWIFT_COMPILATION_MODE = singlefile;