

`init`の引数で受け取った値をstructのプロパティに代入しようとするとエラーが発生します。

`init`の2行目の`selected = state`で

[code]

    self' used before all stored properties are initialized
    
[/code]

というエラーが出てしまいます。

[code]

    struct Icon: View {
        var imageName:String = ""
        @Binding var selected:Bool
    
        init(_ image:String, _ state:Bool) {
            imageName = image
            selected = state
        }
    
        var body: some View {
    
            VStack{
    
                if self.selected{
                    back_selected()
                    Image(imageName)
                        .frame(width: 98,height:95)
                        .clipShape(Circle())
    
                }else{
                    back_normal()
                    Image(imageName)
                        .frame(width: 98,height:95)
                        .clipShape(Circle())
    
                }
    
            }
        }
    }
    
[/code]


CC BY-SA 4.0
2020-02-23T11:36:26.197
63300
2020-02-23T15:08:40.687
37250
question
swift swiftui
Swiftの初期化処理でエラーが発生する


[別質問の回答](https://ja.stackoverflow.com/a/62444/13972)の中でお示ししましたが、`@Binding`のようなpropertyWrapperのアトリビュートがついた変数宣言は、見かけ上、普通の変数宣言のように見せていますが、コンパイラーからは以下のような宣言であると扱われます。

[code]

        var _selected: Binding<Bool>
        var selected: Bool {
            get {
                _selected.wrappedValue
            }
            set {
                _selected.wrappedValue = newValue
            }
        }
    
[/code]

(`@State`の場合と同様、`$selected`なんて計算型プロパティも宣言されたことになるのですが、`@Binding`の場合、あまり便利なものでもないので省略しておきます。)

つまり`Bool`型のプロパティ`selected`は計算型プロパティであり、初期化は不要、使う場合にはインスタンスメソッド同様に、他の全てのインスタンスプロパティが初期化された後でないといけません。

一方、実際のコードには現れない`_selected`の方は初期化が必要な格納型プロパティですので、`selected`を使う前に、こちらを初期化しておかないといけません。

よって、`init`を自前で定義するなら、こんな感じになります。

[code]

        init(_ image: String, _ state: Binding<Bool>) {
            imageName = image
            _selected = state
        }
    
[/code]

この場合、第2引数の`state`は`Bool`型ではなく、`Binding<Bool>`型と言うことになりますから、`true`や`false`などの`Bool`型の定数では初期化できないということになりますが、`@Binding`は一種の「変数への参照」を表すもの(`selected`を操作すると、参照先の変数の値が書き変わる)なので、「定数への参照」ができるのはかえっておかしいと言うことになるでしょう。

なお、`Icon`は構造体なので、自前で`init`を定義しなければ、

[code]

        init(imageName: String, selected: Binding<Bool>)
    
[/code]

と言うシグニチャのイニシャライザが自動生成されますから、そちらを使った方が良いでしょう。


CC BY-SA 4.0
2020-02-23T15:08:40.687
63305
2020-02-23T15:08:40.687
13972
63300
answer