如何在不迭代结果的情况下对Core Data集执行更改?

时间:2011-10-07 13:11:20

标签: objective-c sql cocoa-touch core-data sql-update

如果NSFetchRequest是包含SELECT的SQL查询的核心数据等价物,那么是否有与SQL命令UPDATE等效的核心数据?

或者换句话说,如果我想更改核心数据集上的值,是否有绕过NSFetchRequest的结果

如果您回答'不',我会非常感谢某些参考文档。干杯!

编辑:通过'迭代',我的意思是我知道如何循环实体并更改值:

NSArray *results = [context executeFetchRequest:...];
for (NSManagedObject *object in results) {
    object.value = anotherValue;
}

但如果他们在同一个属性上获得相同的价值,我只想打电话给[context executeChangesOnFetchRequest:...]。当然这种方法不存在,但也许比for-loop更优雅/简洁。

1 个答案:

答案 0 :(得分:4)

嗯,不。如果要对Core Data对象所在的对象上下文进行更改,则必须在所述对象上设置相应的属性,然后在该对象上下文中提交更改。 Core Data将为您处理所有优化。

如果您只想找到一种方法来避免for循环更新结果集中对象的属性,则可以尝试使用makeObjectsPerformSelector:withObject:

NSFetchRequest *req = ...;
NSError *error = nil;
NSArray *results = [self.managedObjectContext executeFetchRequest:req error:&error];
if(error != nil) {
  //oops.
} else {
   //avoid the loop:
   [results makeObjectsPerformSelector:@selector(setSomeProperty:) withObject:someValue];

   if(![self.managedObjectContext save:nil]) {
      //error during save
   }
}

对于喜欢冒险的人,您可以尝试在NSManagedObjectContext 上添加类别:

@interface NSManagedObjectContext (JRAdditions)

- (BOOL) executeChanges:(NSDictionary *) changes 
       withFetchRequest:(NSFetchRequest *) request
                  error:(NSError **) error;
@end

@implementation NSManagedObjectContext (JRAdditions)

- (BOOL) executeChanges:(NSDictionary *) changes 
       withFetchRequest:(NSFetchRequest *) request
                  error:(NSError **) error {

   NSArray *results = [self executeFetchRequest:request error:error];
   if(*error || ![results count]) return NO;

   [results makeObjectsPerformSelector:@selector(setValuesForKeysWithDictionary:)
                            withObject:changes];
   return [self save:error];
}

@end

然后你可以这样称呼它:

NSDictionary *changes = [NSDictionary dictionaryWithObjectsAndKeys:@"value1", @"key1", @"value2", @"key2", nil];
NSFetchRequest *request = ...;
NSError *error = nil;

if([self.managedObjectContext executeChanges:changes withFetchRequest:request error:&error]) {
   //done.
} else {
   //error.
}