// // 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