【问题标题】:How do I work with realm notification if result is updated after notification is initialized?如果在通知初始化后结果更新,我如何使用领域通知?
【发布时间】:2016-12-14 12:34:38
【问题描述】:

我使用带有 Realm 结果的 UITableView 作为它的数据源。结果通过领域通知注册,并在发生更改时很好地更新。但是,同一个表视图有一个搜索栏,可以根据用户搜索查询过滤结果。这也可以正常工作,但如果通知侦听器识别到更新,则节数和行数不匹配。这样做的正确方法是什么?是否可以更新 NotificationToken?

这是初始化通知令牌的代码:

let realm = try! Realm()

results = realm.objects(Person.self).filter("active = '1'").sorted(byProperty: "name", ascending: true)

// Observe Results Notifications
notificationToken = results?.addNotificationBlock { [weak self] (changes: RealmCollectionChange) in

    guard let tableView = self?.tableView else { return }
    switch changes {
    case .initial:
        // Results are now populated and can be accessed without blocking the UI
        tableView.reloadData()
        break
    case .update(_, let deletions, let insertions, let modifications):

        // Query results have changed, so apply them to the UITableView
        tableView.beginUpdates()

        tableView.insertRows(at: insertions.map { IndexPath(row: $0, section: 0) }, with: .automatic)

        tableView.deleteRows(at: deletions.map { IndexPath(row: $0, section: 0) }, with: .automatic)
        tableView.reloadRows(at: modifications.map { IndexPath(row: $0, section: 0) }, with: .automatic)
        tableView.endUpdates()
        break
    case .error(let error):
        // An error occurred while opening the Realm file on the background worker thread
        print("Error: \(error)")
        break
    }
}

此代码根据用户搜索输入更新结果:

func updateSearchResults(for searchController: UISearchController) {

    let searchText = searchController.searchBar.text!

    if searchText.isEmpty == false {

        results = results?.realm?.objects(Person.self).filter("active = '1'")

        results = results?.filter("name BEGINSWITH[c] %@ OR lastName CONTAINS[c] %@", searchText, searchText)

        results = results?.sorted(byProperty: "name", ascending: true)

        self.tableView.reloadData()

    }
    else {

        results = results?.realm?.objects(Person.self).filter("active = '1'").sorted(byProperty: "name", ascending: true)

        self.tableView.reloadData()
    }
}

如果已执行搜索 qwuery 并且在更新领域数据库之前,则会发生 NSRange 异常。

【问题讨论】:

    标签: ios swift uitableview realm


    【解决方案1】:

    您在updateSearchResults() 中覆盖results。通知和notificationToken 与特定的Results 对象和查询相关联。所以如果你用另一个查询覆盖了results,你应该停止之前的通知,然后将通知重新添加到新的results对象中。

    所以updateSearchResults() 方法应该是这样的:

    func updateSearchResults(for searchController: UISearchController) {
        let searchText = searchController.searchBar.text!
        if searchText.isEmpty == false {
            results = results?.realm?.objects(Person.self).filter("active = '1'")
            results = results?.filter("name BEGINSWITH[c] %@ OR lastName CONTAINS[c] %@", searchText, searchText)
            results = results?.sorted(byProperty: "name", ascending: true)
        }
        else {
            results = results?.realm?.objects(Person.self).filter("active = '1'").sorted(byProperty: "name", ascending: true)
        }
    
        notificationToken.stop()
        notificationToken = results?.addNotificationBlock { [weak self] (changes: RealmCollectionChange) in
            guard let tableView = self?.tableView else { return }
            switch changes {
            case .initial:
                tableView.reloadData()
                break
            case .update(_, let deletions, let insertions, let modifications):
                tableView.beginUpdates()
    
                tableView.insertRows(at: insertions.map { IndexPath(row: $0, section: 0) }, with: .automatic)
    
                tableView.deleteRows(at: deletions.map { IndexPath(row: $0, section: 0) }, with: .automatic)
                tableView.reloadRows(at: modifications.map { IndexPath(row: $0, section: 0) }, with: .automatic)
                tableView.endUpdates()
                break
            case .error(let error):
                print("Error: \(error)")
                break
            }
        }
    }
    

    【讨论】:

    • 没想到通知令牌会这样,感谢您的澄清
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多