Skip to content

Instantly share code, notes, and snippets.

@tommybananas
Created November 29, 2015 23:28
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save tommybananas/a3ac47152ae1b058bfdf to your computer and use it in GitHub Desktop.
Save tommybananas/a3ac47152ae1b058bfdf to your computer and use it in GitHub Desktop.
ARC iOS Category for a NSArray and NSDictionary deep copy implementations
//
// DeepCopy.h
//
//
#import <Foundation/Foundation.h>
// Deep -copy and -mutableCopy methods for NSArray and NSDictionary
@interface NSArray (DeepCopy)
- (NSArray*) deepCopy;
- (NSMutableArray*) mutableDeepCopy;
@end
@interface NSDictionary (DeepCopy)
- (NSDictionary*) deepCopy;
- (NSMutableDictionary*) mutableDeepCopy;
@end
//
// DeepCopy.m
//
//
#import "DeepCopy.h"
@implementation NSArray (DeepCopy)
- (NSArray*) deepCopy {
unsigned int count = [self count];
id cArray[count];
for (unsigned int i = 0; i < count; ++i) {
id obj = [self objectAtIndex:i];
if ([obj respondsToSelector:@selector(deepCopy)])
cArray[i] = [obj deepCopy];
else
cArray[i] = [obj copy];
}
NSArray *ret = [NSArray arrayWithObjects:cArray count:count];
return ret;
}
- (NSMutableArray*) mutableDeepCopy {
unsigned int count = [self count];
id cArray[count];
for (unsigned int i = 0; i < count; ++i) {
id obj = [self objectAtIndex:i];
// Try to do a deep mutable copy, if this object supports it
if ([obj respondsToSelector:@selector(mutableDeepCopy)])
cArray[i] = [obj mutableDeepCopy];
// Then try a shallow mutable copy, if the object supports that
else if ([obj respondsToSelector:@selector(mutableCopyWithZone:)])
cArray[i] = [obj mutableCopy];
// Next try to do a deep copy
else if ([obj respondsToSelector:@selector(deepCopy)])
cArray[i] = [obj deepCopy];
// If all else fails, fall back to an ordinary copy
else
cArray[i] = [obj copy];
}
NSMutableArray *ret = [NSMutableArray arrayWithObjects:cArray count:count];
return ret;
}
@end
@implementation NSDictionary (DeepCopy)
- (NSDictionary*) deepCopy {
unsigned int count = [self count];
id cObjects[count];
id cKeys[count];
NSEnumerator *e = [self keyEnumerator];
unsigned int i = 0;
id thisKey;
while ((thisKey = [e nextObject]) != nil) {
id obj = [self objectForKey:thisKey];
if ([obj respondsToSelector:@selector(deepCopy)])
cObjects[i] = [obj deepCopy];
else
cObjects[i] = [obj copy];
if ([thisKey respondsToSelector:@selector(deepCopy)])
cKeys[i] = [thisKey deepCopy];
else
cKeys[i] = [thisKey copy];
++i;
}
NSDictionary *ret = [NSDictionary dictionaryWithObjects:cObjects forKeys:cKeys count:count];
return ret;
}
- (NSMutableDictionary*) mutableDeepCopy {
unsigned int count = [self count];
id cObjects[count];
id cKeys[count];
NSEnumerator *e = [self keyEnumerator];
unsigned int i = 0;
id thisKey;
while ((thisKey = [e nextObject]) != nil) {
id obj = [self objectForKey:thisKey];
// Try to do a deep mutable copy, if this object supports it
if ([obj respondsToSelector:@selector(mutableDeepCopy)])
cObjects[i] = [obj mutableDeepCopy];
// Then try a shallow mutable copy, if the object supports that
else if ([obj respondsToSelector:@selector(mutableCopyWithZone:)])
cObjects[i] = [obj mutableCopy];
// Next try to do a deep copy
else if ([obj respondsToSelector:@selector(deepCopy)])
cObjects[i] = [obj deepCopy];
// If all else fails, fall back to an ordinary copy
else
cObjects[i] = [obj copy];
// I don't think mutable keys make much sense, so just do an ordinary copy
if ([thisKey respondsToSelector:@selector(deepCopy)])
cKeys[i] = [thisKey deepCopy];
else
cKeys[i] = [thisKey copy];
++i;
}
NSMutableDictionary *ret = [NSMutableDictionary dictionaryWithObjects:cObjects forKeys:cKeys count:count];
return ret;
}
@end
@AkamaiBot
Copy link

Who holds the copyright on these and what license are these released under?

@tommybananas
Copy link
Author

This is from stack overflow: https://stackoverflow.com/a/5453600/580487

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment