Глубокое копирование - отличаются ли эти две реализации copyWithZone?

Я видел два несколько разных способа реализации copyWithZone. Они разные?

1-й код:

@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

и 2-й код

@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;
}

Если они разные, что из них правильнее? 1. Я перепутал с [собственным классом] в 1-м. Я знаю о мета-классах в цели c, но нужно ли это в этом куске кода? 2. copy.name = self.name; vs another.obj = [obj copyWithZone: zone] В чем разница между вышеупомянутыми?

1 ответ

Решение
  1. Слабые свойства строки не очень хорошая идея, это означает, что кто-то еще хранит надежную ссылку на вашу строку, иначе она будет освобождена.

Обычно хорошая идея сделать свойства NSString * свойством копирования, поэтому:

@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

Что касается:

[self class]

В этом случае это не возвращаемый метакласс, а просто класс и этот вызов копирования будет полиморфным и может использоваться в подклассах Person. В противном случае copy всегда будет возвращать Person, независимо от того, какой метод подкласса будет вызван.

copy.name = self.name;

против

another.obj = [obj copyWithZone: zone] 

Первый случай - присвоение свойству - как оно обрабатывается, зависит от типа свойства. В случае копирования свойства - это два выражения одинаковы. Второй случай в порядке, учитывая, что SomeOtherObject также реализует глубокое копирование.

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

Другие вопросы по тегам