swift 如何在初始化时更新 viewModel 参数

swift how to update viewModel parameter while init

我遇到了“无法分配给 属性:'self' 是不可变捕获”的问题。我如何调用 API 检查状态并更新“getUpdateSuccess”参数

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
        }

   }
}

如果你想稍后“引用”self(例如,稍后更新同一个实例),self应该是引用类型,而不是值类型。

因此,您可以通过将视图模型设为 class(引用类型)而不是 struct(值类型)来解决此问题。

“模型”对象是值类型的良好候选对象,但“视图模型”通常是引用类型。参见 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


顺便说一句,如果捕获的变量是引用类型与当它是值类型。

对于值类型,捕获列表确保您拥有值的副本:

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

将其与引用类型进行对比,其中捕获列表确保您对引用类型具有强引用:

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

顺便说一句,对于引用类型,您经常会看到带有 weak 关键字的捕获列表,例如 [weak self],如果您想要对 class 而不是强引用。如果您需要防止“强引用循环”(超出本次对话范围的主题),这很常见。 The Swift Programming Language: Strong Reference Cycles for Closures.

中对此进行了讨论

但是,无论是强引用还是弱引用,您处理的不是对象的副本,而是对同一原始实例的“引用”。