Created
November 25, 2013 14:34
-
-
Save advantis/7642084 to your computer and use it in GitHub Desktop.
NSManagedObject category for creating deep copy in another context
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Copyright © 2013 Yuri Kotov | |
// | |
#import <CoreData/CoreData.h> | |
@interface NSManagedObject (ADVCopying) | |
- (instancetype) adv_copyInContext:(NSManagedObjectContext *)context; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Copyright © 2013 Yuri Kotov | |
// | |
#import "NSManagedObject+ADVCopying.h" | |
@implementation NSManagedObject (ADVCopying) | |
- (instancetype) adv_copyInContext:(NSManagedObjectContext *)context | |
{ | |
return [self adv_copyInContext:context withCache:[NSMutableDictionary new]]; | |
} | |
- (instancetype) adv_copyInContext:(NSManagedObjectContext *)context withCache:(NSMutableDictionary *)cache | |
{ | |
NSManagedObject *copy; | |
copy = cache[self.objectID]; | |
if (copy) return copy; | |
copy = [[NSManagedObject alloc] initWithEntity:self.entity insertIntoManagedObjectContext:context]; | |
cache[self.objectID] = copy; | |
// Attributes | |
NSArray *keys = [[self.entity attributesByName] allKeys]; | |
NSDictionary *attributes = [self dictionaryWithValuesForKeys:keys]; | |
[copy setValuesForKeysWithDictionary:attributes]; | |
// Relationships | |
NSDictionary *relationships = [self.entity relationshipsByName]; | |
if (0 == relationships.count) return copy; | |
id enumerator = ^(NSString *key, NSRelationshipDescription *relationship, BOOL *stop) | |
{ | |
if ([relationship isToMany]) | |
{ | |
// TODO: Add support for ordered relationships | |
NSMutableSet *sourceSet = [self mutableSetValueForKey:key]; | |
NSMutableSet *targetSet = [copy mutableSetValueForKey:key]; | |
for (NSManagedObject *value in sourceSet) | |
{ | |
[targetSet addObject:[value adv_copyInContext:context withCache:cache]]; | |
} | |
} | |
else | |
{ | |
NSManagedObject *value = [self valueForKey:key]; | |
value = [value adv_copyInContext:context withCache:cache]; | |
[copy setValue:value forKey:key]; | |
} | |
}; | |
[relationships enumerateKeysAndObjectsUsingBlock:enumerator]; | |
return copy; | |
} | |
@end |
Это слишком наивный код. Объекты в CoreData ВСЕГДА образуют граф, данный же алгоритм является рекурсивным, то есть предполагает, что копируемый объект является деревом...
@des010101 Why don't you say the same in english? I can understand it, but probably other people not.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks, this is the best