無限再帰呼び出しでEXC_BAD_ACCESS

  • 0
    Like
  • 0
    Comment

    Swiftで再帰呼び出しをし続けると、EXC_BAD_ACCESSでプログラムが強制終了します。

    サンプルコード
    import UIKit
    
    class ViewController: UIViewController {
    
        /// メソッドが呼ばれた回数
        var numberOfCalls: Int = 0
    
        override func viewDidLoad() {
            super.viewDidLoad()
            recursiveCall()
        }
    
        /// 再帰呼び出しを行うメソッド
        func recursiveCall() {
            numberOfCalls += 1
            print(numberOfCalls)
            recursiveCall()
        }
    }
    

    シミュレータで実行した場合には約40000回程度、実機のiPhone7で実行した場合には約4000回程度の再帰呼び出しでプログラムが強制終了しました。CPU/メモリに負荷を与える処理のため、実行環境によって最大呼び出し回数が変化しそうです。

    オーバーライドしたメソッドでsuperのメソッドを実行するところをselfのメソッドを呼び出してしまった場合や、コンピューテッドプロパティ内で自身のプロパティを参照してしまった場合に意図せず無限再帰呼び出しとなってしまう場合もあります。

    オーバーライドしたメソッド内で自身のメソッドを呼び出してしまった場合
    override func viewDidLoad() {
        self.viewDidLoad()
    }
    
    コンピューテッドプロパティ内で自身のプロパティを参照してしまった場合
    var computedProperty: Int {
        let some = computedProperty + 1
        return some
    }
    

    なお、コンピューテッドプロパティ内で自身のプロパティを参照してしまった場合は以下のようにワーニングが表示されます。
    Attempting to access 'computedProperty' within its own getter
    image.png