objective-ccopycopywithzone

Deep copy - are these two implementations of copyWithZone different?


I have seen two some a bit different ways for implementing copyWithZone. Are they different?

1st code:

@interface Person : NSObject <NSCopying>

@property (nonatomic,weak) NSString *name;
@property (nonatomic,weak) NSString *surname;
@property (nonatomic,weak) NSString *age;

-(id) copyWithZone:(NSZone *)zone;

@end

//and 1st implementation
@implementation Person
-(id) copyWithZone:(NSZone *)zone
{
Person *copy = [[self class] allocWithZone:zone]; 
copy.name = self.name; //should we use copy.name=[self.name copyWithZone: zone]; ?
copy.age = self.age;
copy.surname = self.surname; //here we make assignment or copying?
return copy;
}
@end

and 2nd code

@interface YourClass : NSObject <NSCopying> 
{
   SomeOtherObject *obj;
}

// In the implementation
-(id)copyWithZone:(NSZone *)zone
{
  // We'll ignore the zone for now
  YourClass *another = [[YourClass alloc] init];
  another.obj = [obj copyWithZone: zone];

  return another;
}

If they are different, what's of them more correct? 1. I confused with [self class] in 1st. I know about meta-classes in objective c, but is it necessary in that chunk of code? 2. copy.name = self.name; vs another.obj = [obj copyWithZone: zone] What's the difference between aforesaid?


Solution

    1. Weak string properties is not a good idea, it means that someone else keeps strong reference for your string, otherwise it will be deallocated.

    Usualy its a good idea to make NSString * properties a copy property, so:

    @interface Person : NSObject <NSCopying>
    
    @property (nonatomic,copy) NSString *name;
    
    ...
    
    //and 1st implementation
    @implementation Person
    -(id) copyWithZone:(NSZone *)zone
    {
    Person *copy = [[self class] allocWithZone:zone]; 
    copy.name = self.name; //assigning here is same as coping, should be enough
    

    As for:

    [self class]
    

    In this case it is not meta class returned, just class and this copy call will be polimorphic and may be used in Person subclasses. Otherwise copy will always return Person, doesnt matter wich subclass's method copy would be called.

    copy.name = self.name;
    

    vs

    another.obj = [obj copyWithZone: zone] 
    

    First case is assigning to property - how it is handled depends on property type. In case of copy property - this two expressions are the same. Second case is allright, given that SomeOtherObject also implements deep copy.

    https://developer.apple.com/library/mac/documentation/general/conceptual/devpedia-cocoacore/ObjectCopying.html