2014-01-12 4 views
2

Какова наилучшая практика для реализации NSCopying в иерархии наследования двух классов? Я хотел бы иметь глубокую копию свойств Square и Shape на копии.Правильный способ реализации NSCopying для класса hiearchy

В 3 вопросов, которые я:

  1. ли оба родителя и ребенок класса нужно объявить, что они реализации NSCopying или достаточно, чтобы только объявить его в базовом классе?
  2. Я видел, как некоторые люди используют [instance copy] вместо [instance copyWithZone:] Это просто предпочтение или правильнее использовать: copyWithZone?
  3. При копировании массивов, это правильно сделать: newObj.list = [[NSArray alloc] initWithArray:self.list copyItems:YES];

Вот что у меня есть:

@interface Shape : NSObject <NSCopying> 
@property (nonatomic, strong) NSString *name; 
@property (nonatomic, strong) NSNumber *sides; 
@property (nonatomic, strong) NSArray *list; 
@end 

@implementation Shape 

- (id)copyWithZone:(NSZone *)zone { 
    Shape *shape = [[[self class] allocWithZone:zone] init]; 

    // Is it correct to use copyWithZone: instead of copy? eg: [self.name copy] 
    shape->_name = [self.name copyWithZone:zone]; 
    shape->_sides = [self.sides copyWithZone:zone]; 
    shape->_list = [[NSArray alloc] initWithArray:self.list copyItems:YES]; 

    return shape; 
} 
@end 

// Does this class also need to declare <NSCopying>? 
@interface Square : Shape 
@property (nonatomic, strong) NSString *color; 
@property (nonatomic, strong) NSArray *corners; 
@end 

@implementation Square 
- (id)copyWithZone:(NSZone *)zone { 
    // Will this ensure a deep copy of the inherited properties? 
    Square *square = [[[self class] allocWithZone:zone] init]; 

    square->_color = [self.color copyWithZone:zone];  
    square->_corners = [[NSArray alloc] initWithArray:self.corners copyItems:YES]; 

    return square; 
} 
@end 
+0

возможный дубликат [Исполнительное NSCopying в Подкласс Подкласс] (HTTP: // StackOverflow. com/questions/4472904/implementation-nscopying-in-subclass-of-subclass) –

+0

Сортировка. Я видел этот вопрос, но он не ответил на все мои вопросы. –

+0

Пожалуйста, будьте более конкретными о своих вопросах. Что именно вы не понимаете? Что именно там не ответили? –

ответ

0

как родитель и ребенок класса нужно объявить, что они реализации NSCopying ли или достаточно, чтобы объявить его только в базовом классе?

Это вопрос стиля. Я вообще не объявляю NSCopying еще раз, но это может обеспечить небольшую ясность, если это не очевидно.

Я видел, как некоторые люди используют [экземплярную копию] вместо [экземпляр copyWithZone:] Это просто предпочтение или его правильное использование: copyWithZone?

Это нормально, чтобы позвонить copy. Зоны не использовались в течение очень долгого времени (я не считаю, что OS X когда-либо использовала их.) Однако вы должны переопределить copyWithZone:.

При копировании массивов, правильно ли это делать: newObj.list = [[NSArray alloc] initWithArray: self.list copyItems: YES];

Да, это необходимо, но этого недостаточно, если объекты в массиве не реализуют глубокую копию в своих copyWithZone:. Обратите внимание, что это вызывает copy, а не mutableCopy. Поэтому, если у вас есть массив изменяемых массивов, вы получите массив массивов. Если вам нужно поддерживать изменчивость, вам нужно позвонить по телефону mutableCopy.

Вы сделали одну ошибку, однако:

// Will this ensure a deep copy of the inherited properties? 
Square *square = [[[self class] allocWithZone:zone] init]; 

Нет, вам нужно позвонить:

Square *square = [super copy]; 
+0

Если копия завершена, как указано, следует ли последующая проверка isequal на существующих и клонированных объектах вернуть true? Должен ли я реализовать пользовательский isEqual? –

+0

Вам понадобится реализовать пользовательский '-isEqual:' и пользовательский '-hash'. По умолчанию '-isEqual' проверяет, что объекты фактически являются одним и тем же объектом. Вы должны всегда реализовывать '-hash', если вы реализуете' -isEqual: '. –

Смежные вопросы