how to

@StateObject passing rules

Jul 4, 2025
langsswift
2 Minutes
224 Words

This is bad and ViewB reinits at unexpected time (can run directly)

1
import SwiftUI
2
3
class Manager: ObservableObject {
4
@Published var cnt: Int = 0
5
}
6
7
class Manager2: ObservableObject {
8
@ObservedObject var m: Manager;
9
init(m: Manager) {
10
self.m = m
11
}
12
13
func f() {
14
self.m.cnt += 1
15
}
34 collapsed lines
16
}
17
18
struct ViewB: View {
19
@ObservedObject var m: Manager
20
@ObservedObject var m2: Manager2
21
init(m: Manager) {
22
print("init")
23
24
self.m = m
25
self.m2 = .init(m: m)
26
}
27
28
var body: some View {
29
Button(action: {
30
print("Clicked")
31
self.m2.f()
32
print("After Clicked")
33
}) {
34
Text("Click me")
35
.font(.system(size: 40))
36
}
37
}
38
}
39
40
struct ContentView: View {
41
@ObservedObject var m = Manager();
42
var body: some View {
43
ViewB(m: self.m)
44
}
45
}
46
47
#Preview {
48
ContentView()
49
}

To fix it (can run directly)

1
import SwiftUI
2
3
class Manager: ObservableObject {
4
@Published var cnt: Int = 0
5
}
6
7
class Manager2: ObservableObject {
8
var m = Manager();
9
init() {
10
}
11
12
func f() {
13
self.m.cnt += 1
14
}
15
}
40 collapsed lines
16
17
struct ViewB: View {
18
@ObservedObject var m2: Manager2
19
@ObservedObject var m: Manager
20
var printer = DeallocPrinter()
21
22
var body: some View {
23
Button(action: {
24
print("***\nClicked")
25
self.m2.f()
26
print(self.m.cnt)
27
print("After Clicked")
28
}) {
29
Text("\(self.m.cnt)")
30
.font(.system(size: 40))
31
}
32
}
33
}
34
35
class DeallocPrinter {
36
deinit {
37
print("deallocated")
38
}
39
}
40
41
struct ContentView: View {
42
@StateObject private var m2: Manager2
43
44
init() {
45
self._m2 = StateObject(wrappedValue: Manager2())
46
}
47
48
var body: some View {
49
ViewB(m2: self.m2, m: self.m2.m)
50
}
51
}
52
53
#Preview {
54
ContentView()
55
}
Article title:@StateObject passing rules
Article author:Julyfun
Release time:Jul 4, 2025
Copyright 2025
Sitemap