有时不使用Swift 5编译器调用子类中的委托方法

Jan*_*orf 16 xcode swift swift5

编辑:正如sunshinejr这里指出的,此问题已修复,将与下一个Xcode / Swift版本一起发布。


在使用Swift 4和Swift 5代码库将Xcode 10.1更新为Xcode 10.2之后,我已经看到很多奇怪的行为。

问题之一是在一个ViewController上不再调用ScrollView委托方法。简化的视图层次结构如下:

| ScrollView (ParentScrollView)
| -- Stack View
| ---- ScrollView (ChildScrollView)
| ---- ScrollView (ChildScrollView)
| ---- ScrollView (ChildScrollView)
Run Code Online (Sandbox Code Playgroud)

它充当具有多个页面的视图:ParentScrollView可以水平滚动,ChildScrollView垂直滚动。

ViewController是所有Scrollview(在Storyboard中设置)的委托,但是scrollViewDidEndDecelerating在滚动任何视图(ParentScrollView或ChildScrollView)时不会调用委托方法(如)。该基类ViewController符合UIScrollViewDelegate

我试过在代码中设置委托,除了不知道自己可能做错了什么。该转换未更改该类中的任何代码,但是在更新之前一切正常。在Swift 5发行说明中,我也通常找不到手势,委托或ScrollView的任何更改。

Swift 5编译器似乎是一个错误。此外,有时它确实起作用,有时却不起作用-所有这些都无需更改任何代码或项目设置。

为什么这不再起作用?有没有其他人经历过类似的行为?

Jan*_*orf 20

编辑:正如sunshinejr这里指出的,此问题已修复,将与下一个Xcode / Swift版本一起发布。


我发现了问题,下面是重现问题的方法。

class A: UIViewController, UIScrollViewDelegate {
    // ...does not implement 'scrollViewDidEndDecelerating'
}

class B: A {
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        // Will not be called!
    }
}
Run Code Online (Sandbox Code Playgroud)

什么有效:

class A: UIViewController, UIScrollViewDelegate {
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        // Probably empty
    }
}

class B: A {
    override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        // Will be called!
    }
}
Run Code Online (Sandbox Code Playgroud)

如果基类未实现委托方法,则编译器似乎认为未实现委托方法。如果仅子类实现它,则找不到它。

我仍然无法解释为什么Swift 5会改变这种行为,但是至少我找到了解决方案。也许有人可以提供进一步的见解?

  • 我可以确认这是问题所在。它导致了我们应用程序中的错误修复以及昨天的升级。 (5认同)
  • Swift 5编译器错误可能会应用于未在关联基类中实现的所有委托方法。更糟的是,此错误有时仅在Release版本中表现出来。 (4认同)