【问题标题】:app crashing and getting error: Object has been deleted or invalidated应用程序崩溃并出现错误:对象已被删除或无效
【发布时间】:2018-08-20 07:32:28
【问题描述】:

我正在尝试使用领域删除所有“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];

知道如何解决这个问题吗?

【问题讨论】:

  • 你应该使用收集通知,如果你这样做了,那么这不会发生

标签: ios objective-c realm


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2015-06-08
    • 1970-01-01
    • 2019-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    • 2017-02-03
    • 1970-01-01
    相关资源
    最近更新 更多