Copying

Making a copy of an object can be complex. If you simply copy the object, that is, the pointer that represents the object, then you have a new pointer to an existing object.

 AClass * newObject = object;

That is often what is wanted. If the object is immutable it probably is just what you want. This is often called a "shallow" copy.

A deep copy produces a new object in new memory space that is functionally equivalent to the original. It is done by using the NSCopy protocol and its method -(id)copyWithZone:(NSZone)zone. You must adopt the protocol and implement this method for your class and decide for each part of the object what should be done.

Copying is applied when the destination object is a property that is given the "copy" attribute instead of "retain" or "assign". A copied object is automatically retained. Copying also happens with a direct message to an object,

    AClass * newObject = [object copy];

If the class is one like NSDictionary that has both mutable and immutable forms, copyWithZone will create an immutable copy. For a mutable copy, adopt <NSMutableCopying> and use -(id)mutableCopyWithZone:(NSZone)zone

Given a class defined this way:

@interface TestClass : NSObject <NSCopying>
{
 NSString * aString;
 NSMutableString * mString;
 NSDictionary * aDictionary;
 float afloat;
}
@property (nonatomic, retain) NSString* aString;
@property (nonatomic, retain) NSMutableString* mString;
@property (nonatomic, retain) NSDictionary * aDictionary;
@property (nonatomic) float afloat;
-(id) init;
@end

The simplest copy would be this shallow version. It is sufficient for most immutable objects.

- (id)copyWithZone:(NSZone *)zone
 {
  return [self retain];
 }

If deep copying is needed,

- (id)copyWithZone:(NSZone *)zone
 {
    TestClass * newObject = [super copyWithZone:zone];
    //make copies of instance vars
    [newObject setAfloat:afloat];
[newObject setAString:aString];
[newObject setMString:[mString copy]];
[newObject setADictionary:aDictionary];
return newObject; }

If the superclass does not implement copyWithZone (NSObject does not):

- (id)copyWithZone:(NSZone *)zone
{
TestClass * newObject = [[[self class] alloc]init];
//make copies of instance vars
[newObject setAfloat:afloat];
[newObject setAString:aString];
[newObject setMString:[mString copy]];
[newObject setADictionary:aDictionary];
return newObject;
}

NSString and NSDictionary, among others, implement NSCopying. NSMutableString and NSMutable Dictionary implement NSMutableCopying.

The NSCopying protocol reference. NSMutableCopying.

Here is a sample project that illustrates copying.

The page was last updated Wednesday, May 16, 2012 7:34 PM