I have a LazyVStack
wrapped in a ScrollView
, and within the LazyVStack
, there is a group of SomeThingView
used to display certain things.
import SwiftUI
var appearCount = 0
class MyObject {
static var count = 0
init(){
MyObject.count += 1
}
deinit {
MyObject.count -= 1
print("deinit ImageCount: \(MyObject.count)")
}
}
struct SomeThingView: View {
@State var object: MyObject? = nil
@State var show: Bool = false
var body: some View {
ZStack {
if show { // <- The issue lies here, with this condition, the image will never be released.
Text("load")
} else {
Text("not load")
}
}
.frame(height: 100)
.onAppear {
show = true
object = MyObject()
appearCount += 1
print("appear \(appearCount)")
}
.onDisappear {
show = false
object = nil // <- Unreferencing the image here, the image should be released.
appearCount -= 1
print("disappear \(appearCount)")
print("disappear ImageCount: \(MyObject.count)")
}
}
}
struct ContentView: View {
var body: some View {
VStack {
ScrollView{
LazyVStack{
ForEach(0..<100) {_ in
SomeThingView()
}
}
}
}
.padding()
}
}
The current issue lies in the fact that the @State var object: MyObject? = nil
within SomeThingView is not being released due to the presence of @State var show: Bool = false
.
As seen above, i set show = true
and object = MyObject()
in the onAppear block, and in onDisappear
, set show = false
and object = nil
. Even though i am not using object
in the view, the presence of the show
condition within the ZStack{}
is preventing the object from being released properly.
some log
disappear 7
disappear ImageCount: 57
init ImageCount: 58
appear 8
disappear 7
disappear ImageCount: 58
init ImageCount: 59
appear 8
disappear 7
disappear ImageCount: 59
init ImageCount: 60
appear 8
disappear 7
disappear ImageCount: 60
init ImageCount: 61
appear 8
However, if I comment out the condition for show within the ZStack, or if I comment out the settings for show in onAppear and onDisappear, everything runs smoothly.
struct SomeThingView: View {
@State var object: MyObject? = nil
@State var show: Bool = false
var body: some View {
ZStack {
// if show { // <- The issue lies here, with this condition, the image will never be released.
// Text("load")
// } else {
// Text("not load")
// }
}
.frame(height: 100)
.onAppear {
show = true
object = MyObject()
appearCount += 1
print("appear \(appearCount)")
}
.onDisappear {
show = false
object = nil // <- Unreferencing the image here, the image should be released.
appearCount -= 1
print("disappear \(appearCount)")
print("disappear ImageCount: \(MyObject.count)")
}
}
}
deinit ImageCount: 9
deinit ImageCount: 8
disappear 7
disappear ImageCount: 8
init ImageCount: 9
appear 8
deinit ImageCount: 8
disappear 7
disappear ImageCount: 8
init ImageCount: 9
appear 8
deinit ImageCount: 8
disappear 7
disappear ImageCount: 8
init ImageCount: 9
appear 8
deinit ImageCount: 8
init ImageCount: 9
appear 9
disappear 8
disappear ImageCount: 9
init ImageCount: 10
appear 9
deinit ImageCount: 9
disappear 8
disappear ImageCount: 9
init ImageCount: 10
appear 9
deinit ImageCount: 9