1
struct GroceryList: View {
  @ObservedObject var coreDataViewModel:CoreDataViewModel = CoreDataViewModel() 
  @StateObject var userPreferences: UserPreferences = UserPreferences()
  @State private var selectedItemsInList: [GroceryItem] = []
  @State private var selection = Set<UUID>()//for check box
  @State private var activeTab:Int = 0 //for active tab

The above View gets initialized 3 times as and when the @State variables selection and activeTab gets initialized. I have a init() in GroceryList: View like given below:

 init() 
{
   print("Grocery List View")
}

Grocery List View gets printed thrice.

Since I instantiate and initialize a CoreData View Model firstly, its fetchItems() in CoreDataViewModel init is also done thrice.

How to avoid initialization happening multiple times?

This is my first SwiftUI app in the development phase with self-learning.Any pointers greatly appreciated.

udGlobal
  • 17
  • 7
  • 1
    We do not control how many times SwiftUI can create view, it is a struct (ie. value), so it can be many times... just don't have view's init heavy, preferably do nothing there except initializing properties.. – Asperi Aug 29 '21 at 09:03

1 Answers1

2

CoreDataViewModel initializes 3 times most certainly because you have @ObservedObject, where you have to have @StateObject. Or you can inject this view model as a parameter, leaving @ObservedObject. Or you can use @EnvironmentObject in conjunction with .environmentObject() view modifier.

Also, if by "view initializes" 3 times, you mean its onAppear gets called multiple times - this means your view does not have stable identity. Check Demystifying SwiftUI talk to learn more, but briefly, you need to ensure that view has a stable structural identity, and/or explicit .id() identity.

eXCore
  • 296
  • 2
  • 8
  • How to give a View stable identity? Hope the https://developer.apple.com/videos/play/wwdc2021/10022/ helps. Any inputs also highly valuable. – udGlobal Aug 29 '21 at 10:20
  • This talk is probably the most useful one about SwiftUI. Clears a lot of things, especially about animation and poor performance. – eXCore Aug 29 '21 at 10:23
  • Making CoreDataViewModel as @EnvironmentObject did it. Now VM does not get fetched 3 times. But view still inits thrice. – udGlobal Aug 30 '21 at 09:54
  • View's init effectively means it or its part rendering. For that to investigate you would need to carefully check what state changes. You can also employ a new tool `let _ = Self._printChanges()` available in iOS 15+. – eXCore Nov 01 '21 at 21:06