#include #include @interface Foo: NSObject { } + foo; - (BOOL) conformsToProtocol: (Protocol *) aProtocol; - (BOOL) respondsToSelector: (SEL) aSelector; - copyWithZone: (NSZone *) zone; - mutableCopyWithZone: (NSZone *) zone; @end @implementation Foo + foo { return [[[Foo alloc] init] autorelease]; } - (BOOL) conformsToProtocol: (Protocol *) aProtocol { BOOL ret = [super conformsToProtocol: aProtocol]; NSLog(@"-[<%@:0x%x> %@<%s>] -> %@", NSStringFromClass([self class]), self, NSStringFromSelector(_cmd), [aProtocol name], ret ? @"YES" : @"NO"); return ret; } - (BOOL) respondsToSelector: (SEL) aSelector { BOOL ret = [super respondsToSelector: aSelector]; if (![NSStringFromSelector(aSelector) hasPrefix:@"description"]) NSLog(@"-[<%@:0x%x> %@%@] -> %@", NSStringFromClass([self class]), self, NSStringFromSelector(_cmd), NSStringFromSelector(aSelector), ret ? @"YES" : @"NO"); return ret; } - copyWithZone: (NSZone *) zone { id ret = [Foo foo]; NSLog(@"-[<%@:0x%x> %@0x%x] -> <%@:0x%x>", NSStringFromClass([self class]), self, NSStringFromSelector(_cmd), zone, NSStringFromClass([ret class]), ret); return ret; } - mutableCopyWithZone: (NSZone *) zone { id ret = [Foo foo]; NSLog(@"-[<%@:0x%x> %@0x%x] -> <%@:0x%x>", NSStringFromClass([self class]), self, NSStringFromSelector(_cmd), zone, NSStringFromClass([ret class]), ret); return ret; } - retain { id ret = [super retain]; NSLog(@"-[<%@:0x%x> %@] -> retainCount = %d", NSStringFromClass([self class]), self, NSStringFromSelector(_cmd), [ret retainCount]); return ret; } @end void isDeepArrayCopy(NSArray *obj1, NSArray *obj2) { id obj1FirstObject = [obj1 objectAtIndex:0]; id obj2FirstObject = [obj2 objectAtIndex:0]; NSLog(@"<%@:0x%x> -> <%@:0x%x>, %@", NSStringFromClass([obj1 class]), obj1, NSStringFromClass([obj2 class]), obj2, (obj1FirstObject == obj2FirstObject) ? ((obj1 == obj2) ? @"retained" : @"shallow") : @"deep(ish)"); } void isDeepDictionaryCopy(NSDictionary *obj1, NSDictionary *obj2) { id obj1FirstObject = [obj1 objectForKey: @"Key"]; id obj2FirstObject = [obj2 objectForKey: @"Key"]; NSLog(@"<%@:0x%x> -> <%@:0x%x>, %@", NSStringFromClass([obj1 class]), obj1, NSStringFromClass([obj2 class]), obj2, (obj1FirstObject == obj2FirstObject) ? ((obj1 == obj2) ? @"retained" : @"shallow") : @"deep(ish)"); } void isDeepSetCopy(NSSet *obj1, NSSet *obj2) { id obj1FirstObject = [obj1 anyObject]; id obj2FirstObject = [obj2 anyObject]; NSLog(@"<%@:0x%x> -> <%@:0x%x>, %@", NSStringFromClass([obj1 class]), obj1, NSStringFromClass([obj2 class]), obj2, (obj1FirstObject == obj2FirstObject) ? ((obj1 == obj2) ? @"retained" : @"shallow") : @"deep(ish)"); } int main(int argc, char **argv) { NSAutoreleasePool *thePool = [[NSAutoreleasePool alloc] init]; NSArray *anArrayCopy; NSArray *aMutableArrayCopy; NSArray *anArrayMutableCopy; NSArray *aMutableArrayMutableCopy; NSMutableArray *aMutableArray = [NSMutableArray arrayWithObject: [Foo foo]]; NSArray *anArray = [NSArray arrayWithObject: [Foo foo]]; NSDictionary *aDictionaryCopy; NSDictionary *aMutableDictionaryCopy; NSDictionary *aDictionaryMutableCopy; NSDictionary *aMutableDictionaryMutableCopy; NSMutableDictionary *aMutableDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys: [Foo foo], @"Key", nil]; NSDictionary *aDictionary = [NSDictionary dictionaryWithObjectsAndKeys: [Foo foo], @"Key", nil]; NSSet *aSetCopy; NSSet *aMutableSetCopy; NSSet *aSetMutableCopy; NSSet *aMutableSetMutableCopy; NSMutableSet *aMutableSet = [NSMutableSet setWithObject: [Foo foo]]; NSSet *aSet = [NSSet setWithObject: [Foo foo]]; NSZone *zone = NSDefaultMallocZone(); while (zone != 0) { NSLog(@"Copying from zone 0x%x -> 0x%x", NSDefaultMallocZone(), zone); NSLog(@"MutableArray -copy"); aMutableArrayCopy = [aMutableArray copyWithZone:zone]; NSLog(@"MutableArray -mutableCopy"); aMutableArrayMutableCopy = [aMutableArray mutableCopyWithZone:zone]; NSLog(@"Array -copy"); anArrayCopy = [anArray copyWithZone:zone]; NSLog(@"Array -mutableCopy"); anArrayMutableCopy = [anArray mutableCopyWithZone:zone]; NSLog(@"MutableArray: %@", aMutableArray); NSLog(@"MutableArrayCopy: %@", aMutableArrayCopy); NSLog(@"MutableArrayMutableCopy: %@", aMutableArrayMutableCopy); NSLog(@"anArray: %@", anArray); NSLog(@"anArrayCopy: %@", anArrayCopy); NSLog(@"anArrayCopy: %@", anArrayMutableCopy); NSLog(@"Test MutableArray against Copy"); isDeepArrayCopy(aMutableArray, aMutableArrayCopy); NSLog(@"Test MutableArray against MutableCopy"); isDeepArrayCopy(aMutableArray, aMutableArrayMutableCopy); NSLog(@"Test Array against Copy"); isDeepArrayCopy(anArray, anArrayCopy); NSLog(@"Test Array against MutableCopy"); isDeepArrayCopy(anArray, anArrayMutableCopy); NSLog(@"MutableDictionary -copy"); aMutableDictionaryCopy = [aMutableDictionary copyWithZone:zone]; NSLog(@"MutableDictionary -mutableCopy"); aMutableDictionaryMutableCopy = [aMutableDictionary mutableCopyWithZone:zone]; NSLog(@"Dictionary -copy"); aDictionaryCopy = [aDictionary copyWithZone:zone]; NSLog(@"Dictionary -mutableCopy"); aDictionaryMutableCopy = [aDictionary mutableCopyWithZone:zone]; NSLog(@"MutableDictionary: %@", aMutableDictionary); NSLog(@"MutableDictionaryCopy: %@", aMutableDictionaryCopy); NSLog(@"MutableDictionaryMutableCopy: %@", aMutableDictionaryMutableCopy); NSLog(@"aDictionary: %@", aDictionary); NSLog(@"aDictionaryCopy: %@", aDictionaryCopy); NSLog(@"aDictionaryCopy: %@", aDictionaryMutableCopy); NSLog(@"Test MutableDictionary against Copy"); isDeepDictionaryCopy(aMutableDictionary, aMutableDictionaryCopy); NSLog(@"Test MutableDictionary against MutableCopy"); isDeepDictionaryCopy(aMutableDictionary, aMutableDictionaryMutableCopy); NSLog(@"Test Dictionary against Copy"); isDeepDictionaryCopy(aDictionary, aDictionaryCopy); NSLog(@"Test Dictionary against MutableCopy"); isDeepDictionaryCopy(aDictionary, aDictionaryMutableCopy); NSLog(@"MutableSet -copy"); aMutableSetCopy = [aMutableSet copyWithZone:zone]; NSLog(@"MutableSet -mutableCopy"); aMutableSetMutableCopy = [aMutableSet mutableCopyWithZone:zone]; NSLog(@"Set -copy"); aSetCopy = [aSet copyWithZone:zone]; NSLog(@"Set -mutableCopy"); aSetMutableCopy = [aSet mutableCopyWithZone:zone]; NSLog(@"MutableSet: %@", aMutableSet); NSLog(@"MutableSetCopy: %@", aMutableSetCopy); NSLog(@"MutableSetMutableCopy: %@", aMutableSetMutableCopy); NSLog(@"aSet: %@", aSet); NSLog(@"aSetCopy: %@", aSetCopy); NSLog(@"aSetCopy: %@", aSetMutableCopy); NSLog(@"Test MutableSet against Copy"); isDeepSetCopy(aMutableSet, aMutableSetCopy); NSLog(@"Test MutableSet against MutableCopy"); isDeepSetCopy(aMutableSet, aMutableSetMutableCopy); NSLog(@"Test Set against Copy"); isDeepSetCopy(aSet, aSetCopy); NSLog(@"Test Set against MutableCopy"); isDeepSetCopy(aSet, aSetMutableCopy); if (zone == NSDefaultMallocZone()) zone = NSCreateZone(NSPageSize(), NSPageSize(), YES); else zone = 0; } [thePool release]; return 0; }