Property wrapper - @ObservedOject, @EnvironmentObject
๐ Property Wrapper๋?
@ObservedObject์ @EnvironmentObject ๋ชจ๋ @State์ @Binding๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก property wrapper ์ ๋๋ค !
- Property wrapper๋ ์์ฑ ๊ฐ์ธ๊ธฐ๋ฅผ ํตํด ์ฝ๋๋ฅผ ๋์ฑ ๊ฐ๊ฒฐํ๊ณ ์ฝ๊ธฐ ์ฝ๊ฒ ๋ง๋๋ ๋ฐ ์ฌ์ฉ๋๋ ๊ธฐ๋ฅ์ ๋๋ค.
- ์ด๋ฅผ ํตํด ์ฝ๋๋ฅผ ๋์ฑ ์ง๊ด์ ์ด๊ณ ๋ช ํํ๊ฒ ์์ฑํ ์ ์์ต๋๋ค.
๐ก @ObservedObject
SwiftUI View๊ฐ ๊ด์ฐฐํด์ผ ํ๋ ์ธ๋ถ ๊ฐ์ฒด๊ฐ ์์ ๋ ์ฌ์ฉ๋ฉ๋๋ค. @ObservedObject๋ ObservableObject ํ๋กํ ์ฝ์ ์ฑํํ์ฌ SwiftUI View์ ์ํธ์์ฉํ ์ ์๋๋ก ๋ง๋ค์ด์ง๋๋ค.
๐ Docs
@ObservedObject ๋ํผ๋ SwiftUI ๋ทฐ์ ObservableObject ๊ฐ์ฒด ๊ฐ์ ์ฐ๊ฒฐ์ ์ค์ ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ObservableObject ๊ฐ์ฒด๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ๋ทฐ๋ ์๋ฆผ์ ๋ฐ๊ณ ์ ๋ฐ์ดํธ๋ ๊ฐ์ ์ฌ์ฉํ์ฌ ๋ค์ ๋ ๋๋ง๋ฉ๋๋ค. ์ด๋ฌํ ๋ํผ๋ ๋ทฐ์ ๊ด์ฐฐ ๋์ ๊ฐ์ฒด ๊ฐ์ ๋ฐ์ธ๋ฉ์ ์์ฑํ์ฌ, ๊ด์ฐฐ ๋์ ๊ฐ์ฒด๊ฐ ๋ณ๊ฒฝ๋๋ฉด ํด๋น ๋ณ๊ฒฝ ์ฌํญ์ด ์๋์ผ๋ก ๋ทฐ์ ์ ๋ฐ์ดํธ๋๋๋ก ํฉ๋๋ค.
class DataModel: ObservableObject {
@Published var name = "Some Name"
@Published var isEnabled = false
}
struct MyView: View {
@StateObject private var model = DataModel()
var body: some View {
Text(model.name)
MySubView(model: model)
}
}
struct MySubView: View {
@ObservedObject var model: DataModel
var body: some View {
Toggle("Enabled", isOn: $model.isEnabled)
}
}
@ObservedObject ์์ฑ์ ์ฌ์ฉํ์ฌ SwiftUI ๋ทฐ์ ๋งค๊ฐ๋ณ์๋ก ObservableObject ์ธ์คํด์ค๋ฅผ ์ ๋ฌํ๊ณ , ํด๋น ๊ฐ์ฒด์ @Published ํ๋กํผํฐ๊ฐ ๋ณ๊ฒฝ๋ ๋ ๋ทฐ๋ฅผ ์ ๋ฐ์ดํธํ ์ ์์ต๋๋ค. ์ด๋ ์ฃผ๋ก StateObject๋ฅผ ์๋ธ๋ทฐ๋ก ์ ๋ฌํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
์์ ์์ ๋ ๋ฐ์ดํฐ ๋ชจ๋ธ์ ObservableObject
๋ก ์ ์ํ๊ณ , ํด๋น ๋ชจ๋ธ์ ๋ทฐ์์ StateObject๋ก ์ธ์คํด์คํ
ํ ๋ค์, ์๋ธ๋ทฐ์ ์ ๋ฌํ๊ธฐ ์ํด @ObservedObject ์์ฑ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
๋ฐ๋ผ์ ์ฌ์ฉ์๊ฐ name
์ด๋ isEnabled
๊ฐ์ ์
๋ฐ์ดํธ ํ๋ฉด, DataModel๊ฐ์ฒด์ @Published ํ๋กํผํฐ
๊ฐ ๋ณ๊ฒฝ๋๊ณ , ์ด๋ฅผ ์์กดํ๊ณ ์๋ MySubView
๊ฐ ์๋์ผ๋ก ์
๋ฐ์ดํธ ๋ฉ๋๋ค.
๋ํ ์๋ธ๋ทฐ์์ ๋ชจ๋ธ ํ๋กํผํฐ๋ฅผ ์ ๋ฐ์ดํธํ ์ ์์ผ๋ฉฐ, ์๋ฅผ ๋ค์ด ์์ ์์ ์์์ฒ๋ผ ํ ๊ธ์ ์ฌ์ฉํ์ฌ ๋ค๋ฅธ ๋ทฐ ๊ณ์ธต ๊ตฌ์กฐ์ ์๋ ๊ด์ฐฐ์๋ค์๊ฒ ์ ํํ ์ ์์ต๋๋ค.
โญ๏ธ ์ ๋ฆฌ
- @ObservedObject ์์ฑ์ ์ฌ์ฉํ ๋, ํด๋น ๊ฐ์ฒด๋ฅผ ๋ทฐ์ ์ ๋ ฅ์ผ๋ก ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์๋ง ์ฌ์ฉํด์ผ ํฉ๋๋ค.
์ฆ, ๊ฐ์ฒด๋ฅผ ๋ทฐ ๋ด๋ถ์์๋ง ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์๋ ๋ค๋ฅธ ์์ฑ(
@StateObject
,@EnvironmentObject
)๋ค์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
-
ObservableObject ๊ฐ์ฒด๋ฅผ ๊ตฌ๋ ํ๊ณ , ๊ฐ์ฒด์ @Published ํ๋กํผํฐ๊ฐ ๋ณ๊ฒฝ๋ ๋ ๋ทฐ๋ฅผ ์ ๋ฐ์ดํธํ ์ ์์ต๋๋ค.
-
ํ์ง๋ง @ObservedObject ์์ฑ์ ๊ธฐ๋ณธ๊ฐ์ด๋ ์ด๊ธฐ๊ฐ์ ์ง์ ํ๋ ๊ฒ์ ๊ถ์ฅ๋์ง ์์ต๋๋ค. โ
๋ง์ฝ ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํํ๊ฑฐ๋, ๋ทฐ ๋ด๋ถ์์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์๋
@StateObject
๋@EnvironmentObject
๋ฑ์ ์์ฑ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
-
๋ฐ๋ผ์ @ObservedObject ์์ฑ์ ์ฃผ๋ก ๋ทฐ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ฑฐ๋, ์ธ๋ถ์์ ์ฃผ์ ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์ ์ฌ์ฉ๋ฉ๋๋ค.
-
์ด๋ฅผ ํตํด SwiftUI์์ ๋ฐ์์ ์ด๊ณ ํจ์จ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
๐ก ObservableObject Protocol
SwiftUI์์ ObservableObject ํ๋กํ ์ฝ์ ๊ด์ฐฐ ๊ฐ๋ฅํ(observable) ๊ฐ์ฒด๋ฅผ ์ ์ํ๊ธฐ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
ObservableObject๋ฅผ ์ค์ํ๋ ๊ฐ์ฒด๋ @Published
์์ฑ์ ์ฌ์ฉํ์ฌ ํด๋น ์์ฑ์ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์๋ฆฌ๋ ๋ฐฉ์์ผ๋ก ๋ค๋ฅธ ๊ฐ์ฒด๋ค์๊ฒ ๋ณ๊ฒฝ ์ฌํญ์ ์๋ฆด ์ ์์ต๋๋ค.
ObservableObject๋ฅผ ์ค์ํ๋ ๊ฐ์ฒด๋ SwiftUI ์ฑ์ ์ํ๋ฅผ ๋ํ๋ด๋ ๋ชจ๋ธ(model) ๊ฐ์ฒด
๋ก ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
์ด ๋ชจ๋ธ ๊ฐ์ฒด๋ ๋ทฐ(view)์ ๋ถ๋ฆฌ๋์ด, ๋ทฐ์ ํ์๋ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๊ณ ์
๋ฐ์ดํธํ๋ ์ญํ ์ ํฉ๋๋ค.
๋ชจ๋ธ ๊ฐ์ฒด๋ฅผ ๋ณ๋๋ก ๊ด๋ฆฌํจ์ผ๋ก์จ, SwiftUI๋ ํด๋น ๊ฐ์ฒด๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ๋ทฐ๋ฅผ ์๋์ผ๋ก ์
๋ฐ์ดํธํ ์ ์๊ฒ ๋ฉ๋๋ค.
class Counter: ObservableObject {
@Published var count = 0
}
์์ ์์์์, Counter ํด๋์ค๋ ObservableObject ํ๋กํ ์ฝ์ ์ค์ํ๊ณ , count ์์ฑ์ @Published ์์ฑ์ผ๋ก ์ ์๋์ด ์์ต๋๋ค. ์ด๋ ๊ฒ ๊ตฌํ๋ Counter ํด๋์ค์ ๊ฐ์ฒด๋ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ๊ด์ฐฐ ๊ฐ๋ฅํ ๊ฐ์ฒด๋ก ๋์ํ๋ฉฐ, ๋ทฐ์ ํจ๊ป ์ฌ์ฉํ ์ ์์ต๋๋ค.
๐ก @EnvironmentObject
SwiftUI View์ ์์ ๋ทฐ์์ ์์ฑ ๋ฐ ๊ด๋ฆฌ๋๋ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ View์์ ์ฌ์ฉ
ํ ์ ์๋๋ก ํฉ๋๋ค.
@EnvironmentObject๋ฅผ ์ฌ์ฉํ๋ฉด View์์ ์ด์ ์ ์์ฑ๋ ๊ฐ์ฒด๋ฅผ ๋ค์ ๋ง๋ค ํ์๊ฐ ์์ผ๋ฏ๋ก, ์ฝ๋๋ฅผ ๋์ฑ ๊ฐ๊ฒฐํ๊ฒ ์์ฑํ ์ ์์ต๋๋ค.
๐ Docs
@EnvironmentObject๋ ์ฃผ๋ก SwiftUI ์ฑ์ ์ํ๋ฅผ ๋ํ๋ด๋ ์ ์ญ์ ์ธ ๊ฐ์ฒด๋ฅผ ๊ด๋ฆฌ
ํ๊ธฐ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
@EnvironmentObject๋ฅผ ์ฌ์ฉํ๋ฉด, ํ์ ๋ทฐ์์ ํด๋น ๊ฐ์ฒด๋ฅผ ์ง์ ์ ๋ฌํ์ง ์๊ณ ๋ ์์ ๋ทฐ์์ ์ ๋ฌํ ๊ฐ์ฒด์ ์ ๊ทผํ ์ ์์ต๋๋ค.
@EnvironmentObject๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋, ๋ค์๊ณผ ๊ฐ์ด ์ธ ๊ฐ์ง ๋จ๊ณ๋ฅผ ๊ฑฐ์ณ์ผ ํฉ๋๋ค.
- ์ ์ญ์ ์ธ ๊ฐ์ฒด๋ฅผ ์ ์ํ๊ณ ObservableObject ํ๋กํ ์ฝ์ ์ค์ํ๋๋ก ๊ตฌํํฉ๋๋ค
- ํด๋น ๊ฐ์ฒด๋ฅผ ์ฑ์ root view์์
environmentObject modifier
๋ฅผ ์ฌ์ฉํ์ฌ ๋ฑ๋กํฉ๋๋ค. - ํ์ ๋ทฐ์์
@EnvironmentObject
์์ฑ์ ์ฌ์ฉํด ๋ฑ๋ก๋ ๊ฐ์ฒด์ ์ ๊ทผํฉ๋๋ค.
โญ๏ธ ์ ๋ฆฌ
class UserData: ObservableObject {
@Published var name = "John Doe"
}
struct ContentView: View {
@EnvironmentObject var userData: UserData
var body: some View {
Text("Hello, \(userData.name)!")
}
}
struct MyApp: App {
let userData = UserData()
var body: some Scene {
WindowGroup {
ContentView().environmentObject(userData)
}
}
}
์์ ์์์์, UserData ํด๋์ค๋ ObservableObject ํ๋กํ ์ฝ์ ์ค์ํ๋๋ก ๊ตฌํ๋์ด ์์ต๋๋ค. ContentView ๋ทฐ์์๋ @EnvironmentObject ์์ฑ์ ์ฌ์ฉํ์ฌ userData ๊ฐ์ฒด์ ์ ๊ทผํฉ๋๋ค. ๋ง์ง๋ง์ผ๋ก, MyApp ์ฑ์์๋ ContentView๋ฅผ environmentObject modifier๋ฅผ ์ฌ์ฉํ์ฌ userData ๊ฐ์ฒด๋ฅผ ๋ฑ๋กํฉ๋๋ค.
- @EnvironmentObject๋ฅผ ์ฌ์ฉํ๋ ๋ทฐ์์๋ ํด๋น ๊ฐ์ฒด์ ์์ฑ์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค ๋ทฐ๋ฅผ ์ ๋ฐ์ดํธํ๋ฏ๋ก, ์ด๋ฅผ ํตํด ์์ ๋ทฐ์์ ๊ด๋ฆฌ๋๋ ์ ์ญ์ ์ธ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.