为什么CoreData不像NSFetchRequest那样提供名为NSDeleteRequest的类

时间:2011-08-07 06:58:05

标签: iphone ios4 core-data iphone-sdk-3.0

我想知道为什么iPhone的CoreData框架不提供使用NSPredicate从组中的数据库中删除对象的工具。他们提供了使用NSFetchRequest获取数据的方法,但是我找不到任何方法或类来删除具有NSPredicate的组中的对象。例如,我想从客户表中删除那些客户余额为零的对象。我可以用核心数据中的for循环执行此操作,但我想知道为什么苹果没有提供以这种方式删除对象的方法?

1 个答案:

答案 0 :(得分:1)

您应该能够使用NSManagedObjectContext的{​​{1}}方法从数据库中删除对象。同样,如果您从核心数据模型创建了.h和.m文件,它应该为对象创建方法,以从其自身中删除一对多关系对象(类似于deleteObject:或{{1 }}

使用此信息,您应该能够设置一个参数来检查余额是否为零,并使用这些方法之一删除对象。一种可能性是偶尔使用获取请求来查找余额为零的所有客户(使用-(void)removeCustomersObject:(Customer *)value)并从数据库中删除获取的结果。我希望这会有所帮助并让你知道该去哪里。我会更加详细,但如果没有更多信息,很难给出太多建议。无论如何,这应该是如何缓解问题的良好基础。

编辑:从核心数据中删除多个对象有两种方法。最简单的假设你有两个实体。一个是父母,我将其称为-(void)removeCustomers:(NSSet *)value,它将所有孩子保持在一对多的关系中。这些将是您的客户或个人对象。你的名字并不太重要,但那些是平衡的对象。对于此示例,我将调用类NSPredicate

如果为实体生成代码(通过转到xcdatamodeld文件,选择实体,然后转到Editor-> Create NSManagedObject Subclass),您将看到父实体的类似内容。

MyDatabase

并在您的.m文件中

Customer

同样,这些是在创建文件时为您创建的,但如果由于某种原因它们不是,则可能没有正确设置关系。

要删除文件,您需要使用谓词来获取上下文。返回的请求是@class Customer; @interface MyDatabase : NSManagedObject { } @property (nonatomic, retain) NSSet *customers; ,其对象与条件匹配(余额为0)。对于此示例,我们只需调用该数组@implementation MyDatabase @dynamic customers - (void)addCustomersObject:(Customer *)value { NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1]; [self willChangeValueForKey:@"customers" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects]; [[self primitiveValueForKey:@"customers"] addObject:value]; [self didChangeValueForKey:@"customers" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects]; [changedObjects release]; } - (void)removeCustomersObject:(Customer *)value { NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1]; [self willChangeValueForKey:@"givenSurveys" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects]; [[self primitiveValueForKey:@"customers"] removeObject:value]; [self didChangeValueForKey:@"customers" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects]; [changedObjects release]; } - (void)addCustomers:(NSSet *)value { [self willChangeValueForKey:@"customers" withSetMutation:NSKeyValueUnionSetMutation usingObjects:value]; [[self primitiveValueForKey:@"customers"] unionSet:value]; [self didChangeValueForKey:@"customers" withSetMutation:NSKeyValueUnionSetMutation usingObjects:value]; } - (void)removeCustomers:(NSSet *)value { [self willChangeValueForKey:@"customers" withSetMutation:NSKeyValueMinusSetMutation usingObjects:value]; [[self primitiveValueForKey:@"customers"] minusSet:value]; [self didChangeValueForKey:@"customers" withSetMutation:NSKeyValueMinusSetMutation usingObjects:value]; } 。在这一点上,我们准备好了解两种可能的解决方案。

1)在此,您没有Core Data的子/父实体地图,只有一个实体。在这种情况下,您将使用如上所述的获取请求。然后你会打电话给以下

NSArray

这会删除所有对象,然后在完成后保存您的上下文。

2)如果你有一个父/子核心数据地图,它会变得更容易。在这种情况下,您只需在获取请求期间调用以下内容

objectsToRemove

第二种方法一次删除所有对象,但确实需要一个包含for (id myObject in objectsToDelete) { [self.managedObjectContext deleteObject:myObject]; } // commit the changes; NSError *error = nil; if (![self.managedObjectContext save:&error]) { // handle the error; } 个对象的实体。在我看来,这是一种更好的方法,虽然没有必要,特别是如果你不需要将[myDatabase removeCustomers:[NSSet setWithArray:objectsToDelete]]; // commit the changes; NSError *error = nil; if (![self.managedObjectContext save:&error]) { // handle the error; } 个对象分成不同的组。这个Core Data tutorial概述了经典的Department和Employees项目,这是一个非常简单但明确的例子,说明了如何在Core Data中使用父/子层次结构。