Delegate methods in child class sometimes not called with Swift 5 compiler

≡放荡痞女 提交于 2019-11-30 02:27:15

EDIT: 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!
    }
}

What does work:

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.

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?

Looks like this issue existed back in 2016 as well and was fixed at one point: https://bugs.swift.org/browse/SR-2919

As Jan pointed out, this is a Swift 5 regression. This is tracked on Swift's JIRA as well as on radar (rdar://problem/49482328). This is also already fixed (PR here) but we need to wait for the next Xcode/Swift release.

Edit: As of Xcode 10.3, we observed that the bug is fixed, but we are still monitoring if it is fixed for good.

We ran into this with a UITextViewDelegate

Another workaround is to add the @objc tag to the method in the superclass

I experienced the same issue only with the release scheme after upgrading to Xcode 10.2. I also tested Xcode 10.3 and it is exactly the same behavior.

For those who don't want to add @objc everywhere in your delegate implementation.

The quick solution is to disable the Swift 5 compiler optimisation in the build settings:

For those who already upgraded to Xcode 10.3, it seems that this build settings option is not visible anymore, but you can still change it directly via the pbxproj file of your project and it should appear in the xcode UI afterward. SWIFT_COMPILATION_MODE = singlefile;

Since all of UIScrollViewDelegate methods are optionals you will never see an error from compiler if it thinks that you didn't implement them, most probably what is happening is that Apple changed method signature in Swift 5 (again) and for some reason the migration tool didn't work.
Check the methods names along with UIScrollViewDelegate updated to USwift 5 documentation, you will see that probably your methods names are different, simply correct them and everything should work again.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!