'swift how to update viewModel parameter while init

I have encountered the problem "Cannot assign to property: 'self' is an immutable capture". How can i call API to check status and update "getUpdateSuccess" parameter

struct HomepageViewModel {

  var getUpdateSuccess: Bool = false

  init() {

       getStatusUpdated.execute().done {
            [self] isUpdated in

            // Cannot assign to property: 'self' is an immutable capture
            self.getUpdateSuccess = isUpdated
        }

   }
}



Solution 1:[1]

If you want to “reference” self later (e.g., update the same instance later), self should be a reference type, not a value type.

So you can solve this by making the view model a class (a reference type) rather than a struct (a value type).

“Model” objects are good candidates for value types, but “view models” are generally reference types. See Value and Reference Types for a discussion of when you might use a value type and when you might use a reference type. For a general discussion, see The Swift Programming Language: Structures and Classes.


By the way, the closure’s capture list syntax (the stuff in between the [ and the ]) has different practical implications if the captured variable is a reference type vs when it is a value type.

With a value type, the capture list makes sure you have a copy of the value:

struct Person {…}

var person = Person(…)
foo { [person] in 
    // this code will be dealing with a safe copy of the original `Person`
}

// maybe you’ll mutate the original `Person` instance here,
// but the above closure will have a copy of the original one

Contrast that with a reference type, where the capture list makes sure you have a strong reference to the reference type:

class ViewModel {
    func bar() {
        baz { [self] in
            // this has a strong reference to this view model instance, not a copy of the instance
        }
    }
}

let viewModel = ViewModel(…)
viewModel.bar()   // any updates that bar does asynchronously, will update this instance of the view model, not a copy of it

As an aside, with reference types, you will often see a capture list with the weak keyword, e.g., [weak self], if you want a “weak” reference to the class rather than a strong reference. This is common if you need to prevent a “strong reference cycle” (a topic beyond the scope of this conversation). This is discussed in The Swift Programming Language: Strong Reference Cycles for Closures.

But, whether a strong reference or weak reference, you are not dealing with a copy of the object, but rather a “reference” to the same original instance.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1