【问题标题】:Swift struct error (Cannot use mutating member on immutable value: 'self' is immutable) using Firebase使用 Firebase 的 Swift 结构错误(不能在不可变值上使用变异成员:'self' 是不可变的)
【发布时间】:2020-08-08 21:51:23
【问题描述】:

我有一个名为 myObjectHolder 的自定义 struct,它有一个名为 myArray 的自定义 struct(称为 myObject)数组。

我尝试获取存储在Firebase-Firesrtore 中的数据并将其附加到数组中(使用将Firebase 文档转换为myObject 的函数)。

我尝试这样做:

struct myObjectHolder {
    var myArray = [myObject]()


    private func fetchMyObjects() {
        let db = Firestore.firestore().collection("myObjects").getDocuments { (querySnapshot, err) in
        for document in querySnapshot!.documents {
            self.myArray.append(self.myObjectFromDocument(document: document)) //Error
        }
    }
}

由于某种原因,当我尝试将新的 myObject 附加到 myArray 时,我收到以下错误消息:

Cannot use mutating member on immutable value: 'self' is immutable

有人知道我该如何解决吗? (我正在使用SwiftUI 这很重要)

谢谢!

【问题讨论】:

标签: ios swift iphone firebase


【解决方案1】:

其他人之前所说的是正确的:您不能修改结构,因此您应该使用类 - 或使结构可修改。更多详情,请查看https://chris.eidhof.nl/post/structs-and-mutation-in-swift/

由于您特别提到了 Firestore,我建议您使用 MVVM 架构:

将您的数据访问逻辑放入视图模型中:

import Foundation
import FirebaseFirestore
import FirebaseFirestoreSwift

class ThingViewModel: ObservableObject {
  @Published var things = [Thing]()

  private var db = Firestore.firestore()

  func fetchData() {
    db.collection("things").addSnapshotListener { (querySnapshot, error) in
      guard let documents = querySnapshot?.documents else {
        print("No documents")
        return
      }

      self.things = documents.map { queryDocumentSnapshot -> Thing in
        return queryDocumentSnapshot.data(as: Thing.self)
      }
    }
  }
}

在你的视图中,实例化视图模型并观察发布的things数组:

struct ThingsListView: View {
  @ObservedObject var viewModel = ThingsViewModel()

  var body: some View {
    NavigationView {
      List(viewModel.things) { thing in
        VStack(alignment: .leading) {
          Text(thing.name)
            .font(.headline)
        }
      }
      .navigationBarTitle("Things")
      .onAppear() {
        self.viewModel.fetchData()
      }
    }
  }
}

此外,对 Swift 结构和类使用 UpperCamelCase 是一种很好的做法:https://github.com/raywenderlich/swift-style-guide#naming

【讨论】:

    【解决方案2】:

    使用 class 而不是 struct 是一种解决方案 - 如果您认为 struct 适合您的设计,请使用

    struct myObjectHolder {
        var myArray = [myObject]()
    
    
        private mutating func fetchMyObjects() {
            let db = Firestore.firestore().collection("myObjects").getDocuments { (querySnapshot, err) in
            for document in querySnapshot!.documents {
                self.myArray.append(self.myObjectFromDocument(document: document)) //Error
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      我刚刚将它从 struct 更改为 class 并且效果很好。

      【讨论】:

        猜你喜欢
        • 2020-10-23
        • 1970-01-01
        • 1970-01-01
        • 2020-01-28
        • 1970-01-01
        • 2016-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多