gpt4 book ai didi

ios - 在 Core Data 中使用级联规则删除托管对象的性能注意事项

转载 作者:可可西里 更新时间:2023-11-01 03:31:25 26 4
gpt4 key购买 nike

我在 SO 中进行了搜索,但没有找到任何建议来提高在处理关系时删除核心数据中的托管对象的性能。

场景很简单。 enter image description here

如您所见,存在三个不同的实体。每个实体都与下一个实体级联。例如,FirstLevelSecondLevel 之间存在称为 secondLevels 的关系。 FirstLevelSecondLevel的删除规则是级联,而SecondLevelFirstLevel 级联无效SecondLevelThirdLevel 之间应用相同的规则。

当我想删除整个图时,我执行如下方法:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"FirstLevel" inManagedObjectContext:context];
[fetchRequest setEntity:entity];

NSError *error = nil;
NSArray *items = [context executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];

// delete roots object and let Core Data to do the rest...
for (NSManagedObject *managedObject in items) {
[context deleteObject:managedObject];
}

利用 Cascade 规则删除图。这对少数对象工作很快,但会降低许多对象的性能。此外,我认为(但我不是很确定)这种类型的删除会执行大量的磁盘往返,我错了吗?

因此,我的问题如下:如何在不利用Cascade 规则的情况下删除图表并提高性能,同时保持图表的一致性?

提前谢谢你。

编辑

我无法删除整个文件,因为我的模型中还有其他实体。

编辑 2

我发布的代码包含在 NSOperation 子类的 main 方法中。该解决方案允许删除阶段在后台执行。由于我利用了Cascade Rule,所以删除是以半自动方式执行的。我只删除了根对象,即 FirstLevel 项目,通过发布代码中的 for 循环。这样 Core Data 就可以为我完成剩下的工作。我想知道的是:是否可以绕过半自动删除操作并手动执行操作而不会丢失图形一致性?

最佳答案

对于遍历和删除数据库中的对象所花费的时间,您无能为力。但是,您可以在后台执行此操作,这样 UI 就不会被阻塞。

例如,类似(代码假定为 ARC - 并且只是键入 - 未编译)...

- (void)deleteAllLevelsInMOC:(NSManagedObjectContext*)moc
{
// Create a context with a private queue, so access happens on a separate thread.
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
// Insert this context into the current context hierarchy
context.parentContext = context;
// Execute the block on the queue of the context
context.performBlock:^{
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"FirstLevel"];
// This will not load any properties - just object id
fetchRequest.includesPropertyValues = NO;
// Iterate over all first-level objects, deleting each one
[[context executeFetchRequest:fetchRequest error:0]
enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[context deleteObject:obj];
}];
// Push the changes out of the context
[context save:0];
}];
}

请注意,您可以将 RootLevel 对象添加到您的数据模型中,并赋予它与第一级对象的一对多关系。然后,(只要你只有一个根对象)你所要做的就是删除那个根对象,它会删除 CoreData 中的所有其他对象。如果您有很多 FirstLevel 对象,那就是要走的路。

或者,您可以将"new"上下文直接连接到持久存储,进行更改,并让其他上下文监视更改通知。

顺便说一句,如果您使用的是 UIManagedDocument,您可以免费获得这种背景,因为已经有一个父上下文在其自己的队列上运行,并且对主上下文的所有更改都传递给父上下文以实际执行数据库工作。

编辑

你可以手动完成,但你必须关闭级联规则。我发现我希望 CoreData 为我做尽可能多的事情。它减少了我犯错误的余地。

如果您已经在后台线程中删除,那么您如何看待性能问题?您必须在删除期间查询...这意味着您正在使用完成所有工作的 MOC。

你应该吸取 UIManagedDocument 的教训。你应该有一个在私有(private)队列上运行的 MOC。它完成所有实际工作。您有一个子 MOC,它只是将工作传递给该工作队列。

如果您实际上正在查询不在您要删除的图中的对象,它们可能会被持久存储协调器的序列化属性挂起。如果是这种情况,您应该考虑使用单独的协调员,或者只拥有两家商店。

这样,您可以根据需要删除图形中的对象,同时仍然响应对其他对象的请求。

关于ios - 在 Core Data 中使用级联规则删除托管对象的性能注意事项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10187695/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com