【问题标题】:Realm - attempt to delete item x from section 0 which only contains 4 items before the update crash领域 - 尝试从第 0 部分中删除项目 x,该部分在更新崩溃之前仅包含 4 个项目
【发布时间】:2017-03-20 10:21:21
【问题描述】:

所以我在我的 collectionview 上使用带有细粒度通知的 Realm。当我选择一个单元格时,我不断收到以下错误:

尝试从第 0 节中删除项目 x,该节在更新前仅包含 4 个项目

我遵循了 Realm 的示例代码,但找不到我做错了什么。我的代码如下:

let producers: Results<Producer> = {
        ProducersRealm().getAllProducers()
    }()
    // receive notification
    var token: NotificationToken?

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.delegate = self
        collectionView.dataSource = self
        registerViewCell()   
        token = producers.addNotificationBlock { [weak self] (changes: RealmCollectionChange) in

            guard (self?.collectionView) != nil else { return }

            // MARK: - Switch on State

            switch changes {

            case .initial:
                self?.collectionView.reloadData()
                break
            case .update(_, let deletions, let insertions, let modifications):
                self?.collectionView.performBatchUpdates({
                    self?.collectionView.insertItems(at: insertions.map({ IndexPath(row: $0, section: 0)}))
                    self?.collectionView.deleteItems(at: deletions.map({ IndexPath(row: $0, section: 0)}))
                    self?.collectionView.reloadItems(at: modifications.map({ IndexPath(row: $0, section: 0)}))

                }, completion: nil)
                break
            case .error(let error):
                print(error.localizedDescription)
                break
            }
        }
  }

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return producers.count
}
 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
            realmProducer = producers[indexPath.row]

          favoriseItemRealm(realmProducer!, textAdded: "addedRetailer", textDeleted: "deletedRetailer", view: self, button: nil)
    }

因此,当用户按下单元格时,这将触发favoriseItemRealm,这将确保出现或不显示心脏图像(在某些单元格上正常工作,但在其他单元格上返回上述错误,虽然我没有删除单元格)。 关于我做错了什么有什么想法吗?

更新: favouriseItemRealm 的代码

  // if object is a Producer
if (object as? Producer) != nil {
    if let downcastObject = object as? Producer {
        let open = realm.objects(Producer.self).filter("id == %@", downcastObject.id).first
        try! realm.write {
            // user is offline
            if hasInternet() == false {
                if open!.favorite != true {
                    open?.favorite = true
                    if userLoggedIn() {
                        // write to dabatase if user is logged in, but offline
                        SyncFavoriteItemRealm.shared.saveOrUpdate((open?.id)!,favorite: true, type: ContentType.PRODUCER.rawValue)
                    }
                } else {
                    open?.favorite = false
                    if userLoggedIn() {
                        // write to dabatase if user is logged in, but offline
                        SyncFavoriteItemRealm.shared.saveOrUpdate((open?.id)!,favorite: false, type: ContentType.PRODUCER.rawValue)
                    }
                }
                // user is online
            } else {
                if open!.favorite != true {
                    open?.favorite = true
                    if userLoggedIn() {
                        //sync to backend
                    }
                    //GoogleAnalyticsHelper.shared.trackFavoriteItem(downcastObject)
                } else {
                    open?.favorite = false
                    if userLoggedIn() {
                        // sync to backend
                    }
                }
            }
        }
    }

}

【问题讨论】:

  • 看看producers.addNotificationBlock你是self?.collectionView.performBatchUpdates调用这个方法。
  • @OlegGordiichuk 是的,我有一个 IBOutlet 弱变量 collectionView: UICollectionView!
  • 每次从 Realm 更新模型时都会执行 performBatchUpdates。所以每次collectionView更新。
  • @OlegGordiichuk 是的,我想在用户每次按下按钮时更新我的​​模型(我的领域数据库 Producer 对象中的“收藏夹”参数已更新)。这样做不正确吗?
  • 你能把favoriseItemRealm的内容贴出来吗?如果您只更新Producer 对象的属性,则deletion 对象中不应该有任何项目。

标签: swift uicollectionview realm performbatchupdates


【解决方案1】:

我遇到了这样的错误,这就是为什么:

我有一个带有帖子的 viewController A。 Posts 是一个带有 Post 领域实体的结果。当点击 tableView 的单元格时,它会导致 viewController B 仅显示一篇帖子。 A 中的令牌仍然有效。如果我从 B 中删除帖子,它会导致触发带有更改的令牌 A。我决定调试并崩溃在self.collectionV.reloadData() 行。如果我评论这一行,我会看到当 B 中的帖子被删除并弹出到 A 时,UICollectionView 中有一个空项目,该帖子在哪里。

有一个领域通知:

realmToken = posts?.observe() { [unowned self] changes in
            switch changes {
            case .initial(_):
                self.collectionV.reloadData()
                break
            case let .update(_, deletions, insertions, modifications):
                self.collectionV.performBatchUpdates({
                    self.collectionV.reloadItems(at: modifications.map { IndexPath(row: $0, section: 0) })
                    self.collectionV.insertItems(at: insertions.map { IndexPath(row: $0, section: 0) })
                    self.collectionV.deleteItems(at: deletions.map { IndexPath(row: $0, section: 0) })
                }, completion: { (completed: Bool) in
CRASH >>>           self.collectionV.reloadData()
                })
                break
            case let .error(error):
                self.show(error: error)
                break
            }
            self.stopLoading()
        }

我认为这可能是因为 UICollectionView 内部行为,但也许有人说清楚了?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多