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