RealityKit Entity.loadAsync method leaks

I am building a simple SwiftUI Augmented Reality app that allows to display a 3D model from a list of models.

ScrollView {
    LazyVGrid(columns: Array(repeating: item, count: 3), spacing: 3) {
        ForEach(items, id: \.self) { item in
            ZStack {
                NavigationLink(destination: ItemDetailsView(item: item))  ) {
                     ListItemCell(item: item, 
                                  itemUUID: "\(item.uuid)",
                                  imageURL: item.imageURL) 
                     }
                }
                .aspectRatio(contentMode: .fill)
            }
        }
}
.navigationTitle("\(list.listName)")

When I tap on a ListItemCell, I load a UIViewRepresentable to display the AR model.

func makeUIView(context: Context) -> ARView {

        // Create arView for VR with background color
        let arView = ARView(frame: .zero, cameraMode: .nonAR, automaticallyConfigureSession: false)
        arView.environment.background = .color(UIConfiguration.realityKit3DpreviewBackgroundColor)
        
        // Set world anchor
        let worldAnchor = AnchorEntity(world: .zero)
        arView.scene.addAnchor(worldAnchor)

        // Load 3D model
        loadAsset(at: worldAnchor, context: context)

        // Setup camera
        setupCamera(on: worldAnchor)

        // Add spot lights
        setupLighting(on: worldAnchor)

        // Install gestures for 3D model
        setupGesturesForARView(arView, context: context)

        // Add camera to coordinator for interactions
        context.coordinator.perspectiveCamera = preview3DViewModel.perspectiveCamera

        return arView
    }

Load Asset:

private func loadAsset(at worldAnchor: AnchorEntity, context: Context) {
        var cancellable: AnyCancellable? = nil

        cancellable = Entity.loadAsync(named: "item")
            .sink(receiveCompletion: { completion in
                if case let .failure(error) = completion {
                    print("Unable to load model: \(error)")
                }
                cancellable?.cancel()

            }) { model in
                if let item = model.findEntity(named: "rootModel") as? ItemEntity {
                    //... do stuff
                    // Add item to ARView
                    worldAnchor.addChild(item)
                }
                cancellable?.cancel()
            }
    }

Everything works fine but I have a memory leak issue. When I profile the app or check the debug memory graph, everytime I load an asset using the Entity.loadAsync method, it leaks a series of blocks as per the screenshot.

The memory footprint grows as I load more models. Whether I load models in real AR or non-AR, it leaks. In AR it eventually crashes when there are too many models and throws an EXC_BAD_ACCESS error on the @main function.

I have tried the following to no effect:

  • loading a simple Apple provided .reality model instead of mine (to check if something was wrong with mine)
  • loading from a function in the coordinator
  • loading from a function in a viewModel as an ObservedObject
  • loading during the UIViewRepresentable init
  • loading during the onAppear {} event in the SwiftUI view

Could you help?

Thanks

EXC_BAD_ACCESS likely indicates that your app is crashing for a reason other than running out of memory, it would be best if you could share a full crash log.

Regarding the memory leaks, there isn't enough information here to determine if your code is the cause of them or not, or even if these leaks are significant (and permanent) enough to result in a problem for your app. For now, I'd suggest starting with the crash log. Then, if you continue to have memory issues, I'd recommend requesting technical support as it will likely require an example project to investigate further.

Hello,

Thanks a lot for your reply. Please see the full crash log below.

Hello,

The crash log indicates an invalid memory fetch, in other words, it looks like RealityKit's physics simulation has dereferenced an invalid pointer. You should file a bug report for this issue using Feedback Assistant, but also note that it is conceivable that your code is causing the issue. If you have a sample project that reproduces this reliably, I recommend attaching it to your bug report, and possibly requesting technical support if you'd like us to check if your code is causing the issue.

Thank you very much. That helped me pinpoint the problem.

After further investigation it seems the leaks happen no matter what when loading any Entity asynchronously. I will file a bug report for that.

They are not causing the crash though.

What causes it is a custom gesture handler installed on the Entities. I will be posting a different question for that or request technical support.

Cheers

RealityKit Entity.loadAsync method leaks
 
 
Q