Skip to content

Instantly share code, notes, and snippets.

@advantis
Created November 25, 2013 14:34
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save advantis/7642084 to your computer and use it in GitHub Desktop.
Save advantis/7642084 to your computer and use it in GitHub Desktop.
NSManagedObject category for creating deep copy in another context
//
// Copyright © 2013 Yuri Kotov
//
#import <CoreData/CoreData.h>
@interface NSManagedObject (ADVCopying)
- (instancetype) adv_copyInContext:(NSManagedObjectContext *)context;
@end
//
// 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
@mazen-kasser
Copy link

Thanks, this is the best

@des010101
Copy link

Это слишком наивный код. Объекты в CoreData ВСЕГДА образуют граф, данный же алгоритм является рекурсивным, то есть предполагает, что копируемый объект является деревом...

@dzensik
Copy link

dzensik commented Mar 31, 2016

@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