はじめに
次のようなSecondView
を作って、ContentView
からアクセスしようとしました。
struct SecondView: View {
private var title = "Greeting"
var text: String
var body: some View {
VStack {
Text(title)
Text(text)
}
}
}
title
はSecondViewでしか使わないし、private
修飾子を付けてました。
すると、ContentView
の方でエラー。
struct ContentView: View {
var body: some View {
VStack {
SecondView(text: "Hello")
//'SecondView' initializer is inaccessible due to 'private' protection level
}
.padding()
}
}
...???
結論
Memberwise InitializerによってContentView
からprivate var
にアクセスしてしまっているので、自分でInitializerを作る
Memberwise Initializer
エラーの意味は、「private
レベルの変数があるので初期化子(イニシャライザ)にアクセスできません」といったもの。
ContentView.swift
の方にあった
SecondView(text: "Hello")
は、Memberwise Initializerというイニシャライザでstruct(SecondView)を初期化しています。
Memberwise Initializerは、自分でinit
を設定しなかった場合に、struct の持つプロパティを全て初期化してくれるものです。
この「全て」が重要で、今回Memberwise Initializerで初期化しようとしたのはSecondView
のtext
だけではありません。すでに"Greeting"
という初期値が設定されているprivate title
も同時に初期化しています。
例えばこんなこともできます。
struct Person {
var name: String
var age = 18
}
let janeDoe = Person(name: "Jane Doe", age: 20)
この場合、janeDoe
というインスタンスは、name
が"Jane Doe"、age
が20として初期化されます。
つまり今回のエラーは、「title
を初期化しようとしたけど、アクセス範囲がprivate
だったからできなかった」ということですね。
アクセス範囲については以下の記事を参照ください。
【Swift】アクセス修飾子【リファクタリング】
ちなみに、classにはMemberwise Initializerは存在しません。classはstructと違い継承機能があり、親クラスのプロパティが追加されるとそれを初期化に反映しないといけなくなるからです。詳しくは以下の記事を参照ください。
https://www.hackingwithswift.com/quick-start/understanding-swift/why-dont-swift-classes-have-a-memberwise-initializer
解決策
自分でinit
を設定すればMemberwise Initializerは機能しなくなるのでエラーが消えます。
struct SecondView: View {
private var title = "Greeting"
var text: String
init(text: String) {
self.text = text
}
var body: some View {
VStack {
Text(title)
Text(text)
}
}
}
SecondView
内で定義したInitializerならprivate
にもアクセスできるので、以下のような書き方もできます。
struct SecondView: View {
private var title: String
var text: String
init(text: String) {
self.text = text
self.title = "Greeting"
}
var body: some View {
VStack {
Text(title)
Text(text)
}
}
}
終わりに
以下の記事も参考にさせていただきました。
https://software.small-desk.com/development/2022/04/19/swift-explain-struct-initializer/
https://qiita.com/jinyogi/items/c1a7e29f086f206602bd