How to perform changes on Core Data set without iterating the results?
If NSFetchRequest
is the Core Data equivalent of an SQL query containing SELECT
, is there a Core Data equivalent of the SQL command UPDATE
?
Or in other wo开发者_JAVA技巧rds, if I want to change values on a Core Data set, is there a way around iterating over the results of an NSFetchRequest
?
In case you're answering with 'no', I'd very much appreciate some kind of reference documentation. Cheers!
EDIT: By 'iteration' I mean that I know how to for-loop over the entities and changes values:
NSArray *results = [context executeFetchRequest:...];
for (NSManagedObject *object in results) {
object.value = anotherValue;
}
But if they're all getting the same value on the same property, I'd just like to call something like [context executeChangesOnFetchRequest:...]
. Of course this method does not exist, but maybe there is a more elegant/concise way than the for-loop.
Well, no. If you want changes to be made on the object context in which the Core Data objects reside, you must set the respective properties on said objects and then commit the changes on that object context. Core Data will handle all the optimizations for you.
If you're simply looking for a way to avoid a for
loop to update properties on objects in the result set, you can try using 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
}
}
For the adventurous, you can try adding a category on 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
You could then call this like so:
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.
}
精彩评论