I am trying to clear up a few things in my head about implementing copyWithZone:
, can anyone comment on the following ...
// 001: Crime is a subclass of NSObject.
- (id)copyWithZone:(NSZone *)zone {
Crime *newCrime = [[[self class] allocWithZone:zone] init];
if(newCrime) {
[newCrime setMonth:[self month]];
[newCrime setCategory:[self category]];
[newCrime setCoordinate:[self coordinate]];
[newCrime setLocationName:[self locationName]];
[newCrime setTitle:[self title]];
[newCrime setSubtitle:[self subtitle]];
}
return newCrime;
}
// 002: Crime is not a subclass of NSObject.
- (id)copyWithZone:(NSZone *)zone {
Crime *newCrime = [super copyWithZone:zone];
[newCrime setMonth:[self month]];
[newCrime setCategory:[self category]];
[newCrime setCoordinate:[self coordinate]];
[newCrime setLocationName:[self locationName]];
[newCrime setTitle:[self title]];
[newCrime setSubtitle:[self subtitle]];
return newCrime;
}
In 001:
Is it best to write the class name directly
[[Crime allocWithZone:zone] init]
or should I use[[[self Class] allocWithZone:zone] init]
?Is it ok to use
[self month]
for copying the iVars or should I be accessing the iVars directly i.e._month
?
You should always use
[[self class] allocWithZone:zone]
to make sure you are creating a copy using the appropriate class. The example you give for 002 shows exactly why: Subclasses will call[super copyWithZone:zone]
and expect to get back an instance of the appropriate class, not an instance of the super class.I access the ivars directly, so I don't need to worry about any side effects I might add to the property setter (e.g., generating notifications) later on. Keep in mind, subclasses are free to override any method. In your example, you are sending two extra messages per ivar. I would implement it as follows:
Code:
Of course, whether you copy the ivars, retain them, or just assign them should mirror what the setters do.
This is my model.
How about this one that implement deep copy:
The default copy behavior of
copyWithZone:
method with SDK provided objects is "shallow copy". That means if you callcopyWithZone:
onNSString
object, it will create a shallow copy but not deep copy. Difference between shallow and deep copy are :A shallow copy of an object will only copy the references to the objects of the original array and place them into the new array.
A deep copy will actually copy the individual objects contained in the object. This done by sending each individual object the
copyWithZone:
message in your custom class method.INSHORT : To get shallow copy you call
retain
orstrong
on all instance variables. To get deep copy you callcopyWithZone:
on all instance variables in your custom classcopyWithZone:
implementation. Now it's your choice to choose.