所以我在Core Data中有一堆对象,希望它们在X天后自动删除(这将基于NSDate)。我做了一些搜索,看起来你一次只能删除一个核心数据对象,而不是一组核心数据对象,更不用说基于特定日期的那些。我想也许有一个循环运行遍历每个对象 - 但这似乎是非常重要的处理器。关于我应该在哪里寻找的任何想法?感谢。
答案 0 :(得分:2)
逐个删除对象的循环是正确的方法。
删除核心数据中的对象非常重要。如果这是一个问题,那么Core Data不适合您的项目,您应该使用其他东西。我推荐FCModel作为一种非常有效的轻量级替代品。
如果您要坚持使用Core Data,那么在后台NSOperationQueue上执行大型操作是个好主意,因此在删除对象时不会锁定主应用程序。您需要非常小心跨多个线程的Core Data,方法是为每个线程创建一个单独的托管对象上下文,两者都使用相同的持久性存储协调器。不要跨线程共享托管对象,但是您可以共享objectID,以在另一个托管对象上下文中获取同一数据库记录的第二个副本。
基本上你的后台线程创建一个新的上下文,删除循环中的所有对象,然后(在主线程上,最好参见文档)保存后台线程上下文。这将合并您的更改,除非存在冲突(两个上下文都修改相同的对象) - 在这种情况下,您有几个选项,我只是中止整个删除操作并重新开始。
Apple提供了很好的文档,可用于解决所有问题和示例代码:https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdConcurrency.html
这有点令人生畏,你需要做一些严肃的家庭作业,但实际的代码很简单,一旦你了解了一切如何运作。或者只使用FCModel,它专为快速批处理操作而设计。
答案 1 :(得分:0)
它并不像您想象的那样处理器繁重:)(当然这取决于数据量)
随意使用循环
- (void)deleteAllObjects
{
NSArray *allEntities = self.managedObjectModel.entities;
for (NSEntityDescription *entityDescription in allEntities)
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entityDescription];
fetchRequest.includesPropertyValues = NO;
fetchRequest.includesSubentities = NO;
NSError *error;
NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *managedObject in items) {
[self.managedObjectContext deleteObject:managedObject];
}
if (![self.managedObjectContext save:&error]) {
NSLog(@"Error occurred");
}
}
}
答案 2 :(得分:0)
正如其他人所说,迭代对象是实际删除Core Data中对象的唯一方法。这是Core Data的方法类型下降的用例之一,因为它没有针对这种用途进行优化。
但是有一些方法可以解决这个问题,以避免您的应用程序出现意外延迟,这样用户就不必等待您的代码突破大量删除请求。
如果您有很多需要删除的对象,并且您不想等到该过程完成,您可以先伪造初始删除,然后稍后进行实际删除。方便的。类似的东西:
toBeDeleted
的实体类型,默认值为NO
。toBeDeleted
(iOS 8中的新增功能)在一个步骤中将YES
设置为NSBatchUpdateRequest
至toBeDeleted
。这个类大多没有文档,所以请查看头文件或BNR blog post about it。您将指定属性名称和新属性值,Core Data将进行大规模,快速更新。NO
是toBeDeleted
。现在,即使它们仍然存在,也会在提取时排除标记为删除的对象。YES
设置为{{1}}的对象。