Home > database >  Large SwiftUI struct leading to memory error
Large SwiftUI struct leading to memory error

Time:11-15

I am still pretty new to iOS development. I have a (very?) large view that is causing a memory error. My body var looks something like this:

var body: some View {
        ZStack {
            Color(...)            
            Rectangle()
            ScrollView {
                VStack {
                    ZStack {
                        RoundedRectangle(...)
                        RoundedRectangle(...)
                                             
                        VStack {
                            ZStack{
                                Circle()                                
                                Circle()
                                Circle()
                                Image(...)
                                
                            }.overlay(
                                 HStack {
                                     // more stuff
                                 }
                            )                            
                        }

                        // many more views
                    }
                }
            }
        }
}

I added and removed views to confirm it was a problem related to having too many views. At some point, when I add another view, I get this (or similar) memory error:

Thread 1: EXC_BAD_ACCESS (code=2, address=0x16cd27fc8)

The address seems to be different each time but always starts with 0x16, which leads me to believe it's a stack overflow... I found this answer/question where they have a very similar problem and were able to solve it by moving large structs to the heap. I am not certain how exactly to accomplish this, even after looking at the example provided in the answer.

My main thought is that there must be a better way to organize my body in the first place that I am just missing. Is using the heap really necessary for rendering a view with a lot of children? Any help or advice is appreciated.

CodePudding user response:

Use LazyVstack Instead Of Vstack it only loads the views we see on the screen.

var body: some View {
        ZStack {
            Color(...)            
            Rectangle()
            ScrollView {
//Vstack load the whole content at a time while LazyVstack load as its needed 
                LazyVStack{ 
                    ZStack {
                        RoundedRectangle(...)
                        RoundedRectangle(...)
                                             
                        VStack {
                            ZStack{
                                Circle()                                
                                Circle()
                                Circle()
                                Image(...)
                                
                            }.overlay(
                                 HStack {
                                     // more stuff
                                 }
                            )                            
                        }

                        // many more views
                    }
                }
            }
        }
}

CodePudding user response:

body has a 10 View limit, break up body into as small custom subviews as possible (based on what let/@State vars each uses).

  • Related