web-dev-qa-db-ja.com

子クラスのデリゲートメソッドがSwift 5コンパイラで呼び出されないことがある

EDIT:sunshinejr が指摘された here として、これは修正され、一緒にリリースされます次のXcode/Swiftバージョン。


Xcode 10.1をXcode 10.2に更新した後、両方のSwift 4とSwift 5のコードベースを使用しています。

問題の1つは、1つのViewControllerでScrollViewデリゲートメソッドが呼び出されなくなったことです。簡略化されたビュー階層は次のとおりです。

| ScrollView (ParentScrollView)
| -- Stack View
| ---- ScrollView (ChildScrollView)
| ---- ScrollView (ChildScrollView)
| ---- ScrollView (ChildScrollView)

複数ページのビューとして機能します。ParentScrollViewは水平方向にスクロールでき、ChildScrollViewsは垂直方向にスクロールできます。

ViewControllerはすべてのScrollview(Storyboardで設定)のデリゲートですが、ビュー(ParentScrollViewまたはChildScrollView)をスクロールするときにデリゲートメソッド(scrollViewDidEndDeceleratingなど)は呼び出されません。 ViewController基本クラスUIScrollViewDelegateに準拠しています。

私はデリゲートをコードで設定しようとしましたが、それ以外は何が間違っているのかわかりません。変換によってクラス内のコードは変更されませんでしたが、更新する前はすべてうまくいきました。 Swift 5リリースノート でも、ジェスチャー、デリゲート、またはScrollViewsへの変更を見つけることができませんでした。

これは、Swift 5コンパイラのバグのようです。さらに、コードやプロジェクトの設定を変更することなく、機能する場合と機能しない場合があります。

なぜこれが機能しないのですか?他の誰かが同様の行動を経験しましたか?

16
Ginger Apps

EDIT:sunshinejr が指摘された here として、これは修正され、一緒にリリースされます次の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!
    }
}

コンパイラは、基本クラスが実装していないデリゲートメソッドは実装されていないと考えているようです。子クラスだけがそれを実装している場合は、それを見つけることができません。

この動作がSwift 5で変化した理由を説明することはできませんが、少なくとも解決策を見つけました。誰かがさらに洞察を提供できるでしょうか?

20
Ginger Apps

私たちはUITextViewDelegateでこれに遭遇しました

もう1つの回避策は、スーパークラスのメソッドに@objcタグを追加することです

4
ndis1

Janが指摘したように、これはSwift 5回帰です。これはSwiftの [〜#〜] jira [〜#〜] およびレーダー( rdar:// problem/49482328)。これも既に修正されています( PRはこちら )が、次のXcode/Swiftリリースを待つ必要があります。

編集:Xcode 10.3の時点で、バグが修正されていることを確認しましたが、完全に修正されているかどうかは引き続き監視しています。

3
sunshinejr

この問題は2016年にも存在し、ある時点で修正されたようです: https://bugs.Swift.org/browse/SR-2919

3
eito

Xcode 10.2にアップグレードした後、リリーススキームでのみ同じ問題が発生しました。 Xcode 10.3もテストしましたが、まったく同じ動作です。

デリゲート実装のどこにでも@objcを追加したくない人のために。

簡単な解決策は、ビルド設定でSwift 5コンパイラの最適化を無効にすることです。

enter image description here

Xcode 10.3に既にアップグレードした人にとって、このビルド設定オプションはもう表示されていないようですが、プロジェクトのpbxprojファイルを介して直接変更でき、後でxcode UIに表示されるはずです。 Swift_COMPILATION_MODE = singlefile;

enter image description here

1
Gomino

すべてのUIScrollViewDelegateメソッドはオプションであるため、実装していないと思われる場合でもコンパイラからのエラーは表示されません。おそらく、Apple changed method Swift 5(繰り返します)の署名で、何らかの理由で移行ツールが機能しませんでした。
メソッド名を確認し、UIScrollViewDelegateをUSwift 5のドキュメントに更新すると、メソッド名が異なることがわかります。メソッド名を修正するだけで、すべてが再び機能するようになります。

0
Andrea