22240


swiftでゲッターセッターを用いようとしたところ、クラッシュしてしまい、原因がわからず困っています。  
おそらく原因となっているコードは

[code]

    internal var height{
        get{return self.height}
        set{
            self.height = newValue
            //その他何かの処理
        }
    }
    
[/code]

実行するとまず、setの部分のset.height = newValueでクラッシュし、  
調べてみると、self.height = newValueがなんども実行されていたためでした。  
つまり、setにおいては何もしなくてもこの処理は行われており、  
書き手が明示的にこのように書く必要はないと勝手に解釈して、以下のように書き換えました

[code]

    internal var height{
        get{return self.height}
        set{
            //self.height = newValue (コメントアウト)
            //その他何かの処理
        }
    }
    
[/code]

すると、今度はgetの部分でクラッシュし、なんどもgetが実行されているようでした。  
getに関してはそのまま返してほしいのですが、

もしかして私がゲッターとセッターの使い方を間違えているのでしょうか。


CC BY-SA 3.0
2016-02-18T11:32:50.067
22238
2016-02-18T12:29:08.330
2016-02-18T11:35:19.377
76
13404
question
swift
getter, setterを使用するとクラッシュする


プロパティの参照方法について誤解があるようです。

> 実行するとまず、setの部分の`set.height = newValue`でクラッシュし、 調べてみると、  
>  `self.height = newValue`がなんども実行されていたためでした。

「`self.height =
newValue`がなんども実行されていた」のは、「setにおいては何もしなくてもこの処理は行われており、書き手が明示的にこのように書く必要はない」からではなく、あなたが「なんども実行され」るようなコードを書いているからです。

Swiftにおいて、`self.height`という書き方は単にプロパティを参照するもので、`self.`を付けたからといって、今定義しようとしているプロパティとは別の何かを参照してくれるわけではありません。従って

[code]

    set {
        self.height = newValue
    }
    
[/code]

と書いてしまうと、プロパティのsetter定義の中で今まさに定義しようとしているsetter自身を呼んでいることになります。当然、無限の再帰呼び出しとなりスタックがあふれたところでクラッシュします。

もうお分かりだと思うのですが、getterの方も同じことが起こっています。

[code]

    get {
        return self.height
    }
    
[/code]

と書いてしまうと、今まさに定義しようとしているgetterの中で、そのgetterを呼んでいるわけです。

Swiftであなたがやろうとしているような処理を書こうとすると、あなたが`self.height`で表そうとしていた何かを明示的に宣言してやる必要があります。

[code]

    private var _height: CGFloat = 0.0
    internal var height: CGFloat {
        get {
            return _height //->自分自身(height)のgetterを呼んではいけない
        }
        set {
            _height = newValue //->自分自身(height)のsetterを呼んではいけない
            //その他何かの処理
        }
    }
    
[/code]

あるいは、こんな書き方の方がSwiftっぽいとしてSwift派の皆さんには好まれるかもしれません。

[code]

    internal var height: CGFloat = 0.0 {
        didSet {
            //その他何かの処理
        }
    }
    
[/code]

お試しください。


CC BY-SA 3.0
2016-02-18T12:29:08.330
22240
2016-02-18T12:29:08.330
13972
22238
answer