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