应用程序崩溃并出现错误:对象已被删除或无效

时间:2018-08-20 07:32:28

标签: ios objective-c realm

我正在尝试使用领域删除“ Lead”类型的所有对象,并尝试使用以下代码:

 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];

有什么办法解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

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循环的每次迭代中打开和关闭事务。我上面发布的示例仅对所有对象执行一个。 :)