有时不使用 Swift 5 编译器调用子类中的委托方法 [英] Delegate methods in child class sometimes not called with Swift 5 compiler
问题描述
正如 sunshinejr 指出的那样 此处,此问题已修复,将与下一个 Xcode/Swift 版本一起发布.
As sunshinejr pointed out here, this has been fixed and will be released together with the next Xcode/Swift version.
在使用 Swift 4 和 Swift 5 代码库将 Xcode 10.1 更新到 Xcode 10.2 后,我看到了很多奇怪的行为.
I've seen a lot of weird behaviour after updating Xcode 10.1 to Xcode 10.2, both with Swift 4 and Swift 5 codebases.
问题之一是在一个 ViewController 上不再调用 ScrollView 委托方法.简化的视图层次如下:
One of the problems is that on one ViewController the ScrollView delegate methods are no longer called. The simplified view hierarchy is as follows:
| ScrollView (ParentScrollView)
| -- Stack View
| ---- ScrollView (ChildScrollView)
| ---- ScrollView (ChildScrollView)
| ---- ScrollView (ChildScrollView)
它充当具有多个页面的视图:ParentScrollView
可以水平滚动,ChildScrollView
可以垂直滚动.
It acts as a view with several pages: ParentScrollView
can be scrolled horizontally, the ChildScrollView
s vertically.
ViewController 是所有 Scrollview 的委托(在 Storyboard 中设置),但是在滚动任何视图(ParentScrollView 或 ChildScrollView)时不会调用委托方法(如 scrollViewDidEndDecelerating
).ViewController
的基类符合UIScrollViewDelegate
.
The ViewController is the delegate of all Scrollviews (set in Storyboard), but the delegate methods (like scrollViewDidEndDecelerating
) are not called when scrolling any of the views (ParentScrollView or ChildScrollView). The base class of ViewController
conforms to UIScrollViewDelegate
.
我尝试在代码中设置委托,除此之外我不知道我可能做错了什么.转换没有更改类中的任何代码,但在更新之前一切正常.在 Swift 5 Release 中,我也找不到对手势、委托或滚动视图的任何更改备注.
I have tried setting the delegates in code, other than that I have no idea what I could be doing wrong. The conversion did not change any code in the class, but everything worked well before updating. I also couldn't find any changes to gestures, delegates or ScrollViews in general in the Swift 5 Release Notes.
这似乎是 Swift 5 编译器的一个错误.此外,有时它会起作用,有时不起作用 - 无需更改任何代码或项目设置.
This seems to be a bug with the Swift 5 compiler. Additionally, sometimes it does work, sometimes it doesn't - all without changing any code or project settings.
为什么这不再起作用?有没有其他人遇到过类似的行为?
Why does this no longer work? Has anyone else experienced similar behaviour?
推荐答案
As sunshinejra> 指出此处,此问题已修复,将与下一个 Xcode/Swift 版本一起发布.
As sunshinejr pointed out here, this has been fixed and will be released together with the next Xcode/Swift version.
我发现了问题,这是重现它的方法.
I've found the issue, here's how to reproduce it.
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!
}
}
如果基类没有实现委托方法,编译器似乎认为它没有实现.如果只有子类实现了,就找不到了.
The compiler seems to think that a delegate method is not implemented if the base class did not implement it. If only the child class implements it, it can't find it.
我仍然无法解释为什么这种行为在 Swift 5 中发生了变化,但至少我找到了解决方案.也许有人可以提供进一步的见解?
I still can't explain why this behaviour changed with Swift 5, but at least I've found a solution. Maybe someone can give further insights?
这篇关于有时不使用 Swift 5 编译器调用子类中的委托方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!