当数据源是结果对象时如何使用领域进行接口驱动的写入

时间:2019-08-01 05:40:49

标签: swift realm

interface-driven write的领域文档指示您可以将记录添加到这样的集合中:

func insertItem() throws {
  // Perform an interface-driven write on the main thread:
  collection.realm!.beginWrite()
  collection.insert(Item(), at: 0)
  // And mirror it instantly in the UI
  tableView.insertRows(at: [IndexPath(row: 0, section: 0)], with: .automatic)
  // Making sure the change notification doesn't apply the change a second time
  try collection.realm!.commitWrite(withoutNotifying: [token])
}

这似乎意味着表的数据源是Array,因为insert集合上没有Results<Item>方法。

在这种情况下,collection是什么数据类型?看来这是一个数组,但我的理解是您无法在数组上创建Realm通知。

我还读到将所有Realm对象复制到一个数组(出于性能原因)不是一个好主意,因为结果是延迟访问的。但是,除非您这样做,否则似乎无法进行接口驱动的写入。 ?

关于如何正确设置此设置的任何建议?

1 个答案:

答案 0 :(得分:1)

文档有点含糊,但是您问题的具体答案是,在这种情况下,集合是List类型。请参阅Collections的文档。

要深入研究,这是一个示例实现。

假设我们有一个Person对象,每个人都有一个Dog对象的List属性。

class PersonClass: Object {
    @objc dynamic var person_name = ""
    let dogs = List<DogClass>()
}

class DogClass: Object {
    @objc dynamic var dog_name = ""
    @objc dynamic var dog_age = 0
    let owners = LinkingObjects(fromType: PersonClass.self, property: "dogs")
}

我们想知道某个特定的人何时养了一条新狗,立即用该狗信息更新我们的tableView,而不会收到事件的领域通知。

这里是设置让·卢克(Jean-Luc)狗的观察者的代码。

//a class var for the notification and the List.
var dogListNotificationToken: NotificationToken? = nil
var dogList: List<DogClass>? = nil

func doObserveDogList() {
    if let realm = gGetRealm() { //using a singleton Realm for this example
        let personResults = realm.objects(PersonClass.self).filter("name == 'Jean-Luc'")
        let firstPerson = personResults.first
        self.dogList = firstPerson?.dogs
    }

    if self.dogList == nil {
        print("there were no dogs for this person")
        return
    }

    self.dogListNotificationToken = self.dogList!.observe { (changes: RealmCollectionChange) in
        switch changes {
        case .initial:
            print("initial object load complete")
            if let results = self.dogList {
                for d in results {
                    print(d.dog_name, d.dog_age)
                }
            }
            break

        case .update(_, let deletions, let insertions, let modifications):
            print(" handle item delete, insert or mod")

            for index in deletions {
                print("  deleted object at index: \(index)")
            }

            for index in insertions {
                print("  inserted object at index: \(index)")
            }

            for index in modifications {
                print("  modified object at index: \(index)")
            }

            break

        case .error(let error):
            // An error occurred
            fatalError("\(error)")
            break

        }
    }
}

并假设让·卢克(Jean-Luc)得到了一只新狗,所以我们需要将它插入领域,但由于我们想“立即”处理它,因此不希望收到通知。

func insertDog() {
    let dogToAdd = DogClass()
    dogToAdd.dog_name = "Number 1"
    dogToAdd.dog_age = 5
    self.dogList?.realm?.beginWrite()
    self.dogList?.insert(dogToAdd, at: 0)
    //insert into tableView/datasource/whatever
    try! self.dogList?.realm!.commitWrite(withoutNotifying: [self.dogListNotificationToken!])
}

以上内容将导致“ 1号狗”被添加到Jean-Luc的狗列表中,插入时不会触发观察事件。