Here's a self-contained example that leaks memory for me.
( Xcode Version 14.2 (14C18)
Running on an iPhone 12 Pro, iOS Version 16.2)
Should I be doing something more to the old ModelEntity
instances to clean them up than .removeFromParent()
?
When the frame counter at the top of the display gets to 5000, memory usage is > 1Gb and climbing linearly.
Comparing exported memgraph files from short and long runs shows that the long run has accumulated 10s of thousands of NSArray instances.
Examining one shows that it's a __NSSingleObjectArrayI
referenced by one REPrivateBufferMeshPayload
and it references a REMeshPartDescriptor.
Not sure if this suggests any approach to avoid this memory leak to anyone? I'm new here.
Thanks.
import SwiftUI
import RealityKit
import simd
struct ContentView : View {
@State var t: Double = 0.05
@State var r: Double = 0.05
@State var n: Int = 0
let timer = Timer.publish(every: 1.0/30.0, on: .main, in: .common).autoconnect()
var body: some View {
ZStack {
ARViewContainer(t: $r).edgesIgnoringSafeArea(.all).onReceive(timer) { _ in
t = t + 0.05
r = 0.15 + 0.1*sin(t)
n += 1
}
VStack{
Text("\(n)")
Spacer()
}
}
}
}
struct ARViewContainer: UIViewRepresentable {
@Binding var t: Double
func makeUIView(context: Context) -> ARView {
let arView = ARView(frame: .zero)
let anchor = AnchorEntity(
.plane([.horizontal],
classification: [.table, .floor],
minimumBounds: [0.05, 0.05]
)
)
arView.scene.anchors.append(anchor)
return arView
}
func updateUIView(_ uiView: ARView, context: Context) {
let anchor = uiView.scene.anchors[ uiView.scene.anchors.endIndex - 1 ]
var to_remove: [Entity] = []
for c in anchor.children {
to_remove.append(c)
}
let _ = to_remove.map {c in c.removeFromParent()}
var descr = MeshDescriptor(name: "ring")
descr.positions = MeshBuffers.Positions( vertices_simd(t) )
descr.primitives = .triangles( triangles() )
let ring_entity = ModelEntity(
mesh: try! .generate(from: [descr]),
materials: [SimpleMaterial(color: .orange, isMetallic: true)]
)
ring_entity.setParent(anchor)
}
}
func triangles()-> [UInt32] {
let nh = 20
let nr = 40
var ind : [UInt32] = []
let n = ( nr )
for i in 0..<(nh-1) {
for j in 0..<(nr-1) {
ind = ind + [ (i*n + j) , (i+1 )*n + j , ((i+1)*n + j+1) ].map{UInt32($0)}
ind = ind + [ (i*n + j) , ((i+1)*n + j+1) , ((i)*n + j+1) ].map{UInt32($0)}
}
}
return ind
}
func vertices_simd(_ r: Double)-> [simd_float3] {
let nh = 20
let nr = 40
let rt:Double = 0.01
let y:Double = 0.01
var vertices:[simd_float3] = []
for i in 0..<nh {
for j in 0..<nr {
let theta = (Double.pi * 2.0 * Double(j)/(Double(nr)-1.0))
let phi = (Double.pi * 2.0 * Double(i)/(Double(nh)-1.0))
let x = Float((r + rt*cos(phi) )*cos(theta))
let y = Float(y + rt*sin(phi))
let z = Float((r + rt*cos(phi) )*sin(theta))
let v = simd_float3(x,y,z)
vertices.append( v )
}
}
return(vertices)
}