【问题标题】:How do I update my Realm Variable when I click on a button?单击按钮时如何更新我的领域变量?
【发布时间】:2021-10-30 12:01:44
【问题描述】:

您好,我正在尝试使用以下代码从领域中名为“book”的对象更改变量“category”:

                  alert.addAction(UIAlertAction(title: "Reading", style: .default, handler: { (_) in
                try! realm.write {
                     let category = "reading"
                            let book = Book()
                            book.category = category
                   }
              }

当我签入 mangoDB realm studio 时,对象类别尚未更新。我看过的教程使用了相同的功能。这是整个更新的代码:

  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    func showmethisfunction() {
        let realm = try! Realm()
        let boook = Book()
        
        
        let alert = UIAlertController(title: "Want to put your book in a list?", message: "Please Select an Option", preferredStyle: .actionSheet)

        alert.addAction(UIAlertAction(title: "Read", style: .default, handler: { (_) in
                 try! realm.write
                {
                    boook.category = "read"
                   }
              }))

              alert.addAction(UIAlertAction(title: "Want to read", style: .default, handler: { (_) in
                try! realm.write {
                    boook.category = "wanttoread"
                   }
              }))

              alert.addAction(UIAlertAction(title: "Reading", style: .default, handler: { (_) in
                try! realm.write {
                    let category = "reading"
                    boook.category = category
                   }
              }))

              alert.addAction(UIAlertAction(title: "Dismiss", style: .cancel, handler: { (_) in
                  print("User click Dismiss button")
              }))

              self.present(alert, animated: true, completion: {
                  print("completion block")
              })
    }
showmethisfunction()
}

我使用了一个类似的警报控制器手动添加一本书,这很有效,但当我想从书中添加变量时它就不起作用了

【问题讨论】:

  • 您问题中的代码非常正确。我的猜测是您使用 Realm Studio 打开了错误的 .realm 文件,因此您看不到更新。此外,问题boookbook 中有两个不同的变量,这可能会导致混淆。当您这样做let book = Book() 时,它将创建一个全新的图书对象,而不是更新现有的。
  • 该代码实际上应该更新现有变量,因为它是在我点击 tableview cel 时触发的。我也用我的分段控件尝试了这个,但它不起作用,我如何将代码更改为更新现有书籍?
  • 如果我的评论正确,我必须使用:let book = realm.objects(Book.self)。但随后我收到以下错误“结果”类型的值没有成员“类别”
  • 嗯,是的,也不是。此代码 let book = realm.objects(Book.self) 不读取书籍对象 - 变量最好表示为 bookResults,因为它将读取所有书籍对象。您收到的错误是因为 Results 对象没有 category 参数 - 只有一个 book 对象具有该属性。我会添加一个答案。

标签: swift xcode filter realm


【解决方案1】:

重申问题:

如何更新现有对象的属性

有许多不同的方法可以做到这一点,其中一些答案取决于对象模型。

一般来说,大多数对象都会有一些称为主键的唯一标识符,如果您知道该标识符,更新对象是一件轻而易举的事

class PersonClass: Object {
    @objc dynamic var _id = ObjectId.generate()
    @objc dynamic var name = "Jay"

    override static func primaryKey() -> String? {
        return "_id"
    }
}

ObjectId 在实例化时将为每个对象生成一个唯一的_id。如果你知道主键,你可以像这样更新一个对象

try! realm.write {
    realm.create(PersonClass.self, value: ["id": "1", "name": "Jay 2"], update: .modified)
}

这假设您要更新的现有对象的主键为“1”,并将对象的名称属性更新为 Jay 2

您也可以通过主键读取对象然后更新它

if let jay = realm.object(ofType: PersonClass.self, forPrimaryKey: "1") {
    try! realm.write {
        jay.name = "Jays new name"
    }
}

最后,您可以运行查询以获取具有匹配属性的 一个 对象(但不要这样做)

if let jay = realm.objects(PersonClass.self).filter("name == 'Jay'").first {
    try! realm.write {
        jay.name = "Jays new name"
    }
}

最后一个选项通常有点“危险”,因为它将过滤所有名为“Jay”的 PersonClass 对象,结果将是无序的,因此first 在不同时间可能会有所不同......所以这里的关键是“不要这样做”。

作为旁注,除非您指定 .sorted(byKeyPath:,否则领域结果是无序的。

【讨论】:

    【解决方案2】:

    首先获取可以更新的对象。 我给出了使用过滤器的例子。你可以使用任何。

    do {
         let realm = try Realm()
         let book = realm.objects(Book.self).filter({ $0.id == id }).first
            try realm.write {
                book?.category = category
            }
        } catch { }
    

    或从此链接获取想法 https://docs.mongodb.com/realm-legacy/docs/swift/latest/index.html#models

    转到上述链接中的自动更新对象部分。

    更新您的问题后,我更新了我的答案。 换行 let boook = Book() 与此行 let boook = realm.objects(Book.self).first ?? Book()

    【讨论】:

    • 如果我在写之前使用 let book = realm.objects(Book.self) 我收到错误消息:'Results' 类型的值没有成员'category'。尽管我在 Realm Studio 中进行了检查,但它肯定具有类别的价值..
    • @Mischa 这个答案与问题没有任何关系。显示如何读取 existing 书籍对象然后更新属性是正确的,但代码是您的问题是使用let book = Book() 实例化一个新书籍对象,然后更新一个属性,即正确的。例如这个答案没有错,但不是您问题的答案,因为您问题中的代码是正确的。
    • 这会有问题。领域对象是无序的,并且获得“第一个”对象可以是具有匹配 id 的任意数量的对象。这个realm.objects(Book.self).first 会更糟,因为它会从 Realm 获取 any 对象 - 仅取决于它当时认为 first 的内容。
    猜你喜欢
    • 2021-06-18
    • 1970-01-01
    • 2016-09-18
    • 1970-01-01
    • 1970-01-01
    • 2022-12-23
    • 1970-01-01
    • 2018-09-06
    • 1970-01-01
    相关资源
    最近更新 更多