应用程序崩溃并收到错误:对象已被删除或失效

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了应用程序崩溃并收到错误:对象已被删除或失效相关的知识,希望对你有一定的参考价值。

我正在尝试删除所有“Lead”类型的对象,使用realm,我尝试使用此代码:

 RLMResults<Lead *> *allLeads = [Lead allObjects];
    for (RLMObject *object in allLeads) {
        RLMRealm *realm = [RLMRealm defaultRealm];
        [realm transactionWithBlock:^{
        [realm deleteObject:object];
        }];
        [realm refresh];
    }

使用此应用程序后崩溃,我正在尝试重新加载tableView时收到此错误:

 if (!obj->_row.is_attached()) {
        @throw RLMException(@"Object has been deleted or invalidated.");
    }

更新:我尝试了以下,但也没有工作,它删除了一切,但它也崩溃了,我发现问题是在[tableview reloadData]:

[realm beginWriteTransaction];
[realm deleteAllObjects];
[realm commitWriteTransaction];

任何想法如何解决这个问题?

答案

Realm需要注意的一件事是,如果保留RLMObject,然后将其删除,之前保留的引用仍将存在于内存中,但显然已删除了基础后备数据。

例如:

// Get the first Lead object
Lead *firstLead = [Lead allObjects].firstObject;

// Delete it from the Realm in which it is stored
[firstLead.realm transactionWithBlock:^{
   [firstLead.realm deleteObject:firstLead];
}];

// Try to read data after it was deleted
NSString *name = firstLead.someString; // Will throw the RLMException

尽管尝试访问任何持久化属性都会触发异常,但您可以通过在尝试执行此操作之前检查firstLead.invalidated是否为YES来避免这种情况。

基本上,如果您的表视图保留任何对象(即,您可能为每个单元格分配了Lead对象),则需要完成并完全删除对这些对象的任何引用。您应该能够在异常调用堆栈中看到哪个已删除的对象正在尝试再次调用。需要在删除对象的同时删除此引用,或者只是事先检查invalidated

另外,关于上面的代码,有一种更高效的编写方式。

RLMResults<Lead *> *allLeads = [Lead allObjects];
RLMRealm *realm = [RLMRealm defaultRealm];

[realm transactionWithBlock:^{
   [realm deleteObjects:allLeads];
}];

在Realm中,最佳实践是最小化您需要执行的写入事务的数量。在您的示例中,您将在for循环的每次迭代中打开和关闭事务。我上面发布的示例仅对所有对象执行一个。 :)

以上是关于应用程序崩溃并收到错误:对象已被删除或失效的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI + Realm:从列表中删除一行会导致异常“RLMException”,原因:“对象已被删除或失效。”

为啥我会在 pytest-qt 中收到此“包装的 C/C++ 对象...已被删除”错误?

内部 C++ 对象已被删除(pyside)

在“设置”片段中夸大类PreferenceScreen的错误

切换到浅色模式时应用程序崩溃

jslint 是不是有缩进选项或已被删除?