Is the copyWithZone (See Below) correct, particularly the bit where I use the setters to populate the instance variables of the new object?
@interface Planet : NSObject <NSCopying>
{
NSString *name;
NSString *type;
NSNumber *mass;
int index;
}
@property(copy) NSString *name;
@property(copy) NSString *type;
@property(retain) NSNumber *mass;
@property(assign) int index;
-(void)display;
@end
-(id) copyWithZone: (NSZone *) zone {
Planet *newPlanet = [[Planet allocWithZone:zone] init];
NSLog(@"_copy: %@", [newPlanet self]);
[newPlanet setName:name];
[newPlanet setType:type];
[newPlanet setMass:mass];
[newPlanet setIndex:index];
return(newPlanet);
}
Is this a better way?
-(id) copyWithZone: (NSZone *) zone {
Planet *newPlanet = [[[self class] allocWithZone:zone] init];
[newPlanet setName:[self name]];
[newPlanet setType:[self type]];
[newPlanet setMass:[self mass]];
[newPlanet setIndex:[self index]];
return(newPlanet);
}
many thanks
gary
(Assuming deep copy is what you want) for the copy we want to make, use copyWithZone: for object instance variables and simply set primitive instance variables using =.
- (id)copyWithZone:(NSZone *)zone
{
MyClass *copy = [[MyClass alloc] init];
// deep copying object properties
copy.objectPropertyOne = [[self.objectPropertyOne copyWithZone:zone] autorelease];
copy.objectPropertyTwo = [[self.objectPropertyTwo copyWithZone:zone] autorelease];
...
copy.objectPropertyLast = [[self.objectPropertyLast copyWithZone:zone] autorelease];
// deep copying primitive properties
copy.primitivePropertyOne = self.primitivePropertyOne
copy.primitivePropertyTwo = self.primitivePropertyTwo
...
copy.primitivePropertyLast = self.primitivePropertyLast
// deep copying object properties that are of type MyClass
copy.myClassPropertyOne = self.myClassPropertyOne
copy.myClassPropertyTwo = self.myClassPropertyTwo
...
copy.myClassPropertyLast = self.myClassPropertyLast
return copy;
}
But notice how properties of the same class as self and copy must be set without copyWithZone:. Otherwise, these objects will call this copyWithZone again, and will try to set their myClassProperties using copyWithZone as well. This triggers an unwanted infinite loop. (Also, you could call allocWithZone: instead of alloc: but I'm pretty sure alloc: calls allocWithZone: anyway)
There are some cases where using = to deep copy object properties of the same class might not be the thing you want to do, but in ALL CASES (as far as I'm aware) deepcopying object properties of the same class with copyWithZone: or anything that calls copyWithZone: will result in an infinite loop.
Whether it's an unwanted copy or not is for you to decide. The reason to synthesize accessors with the copy qualifier is to be sure of the ownership of those objects.
Keep in mind though, that immutable objects like an NSNumber or an NSString won't actually duplicate their storage when they're sent a -copy message, they'll just increase their retain counts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With