У меня небольшая иерархия классов, для которой у меня возникли проблемы с реализацией copyWithZone:
. Я прочитал документацию NSCopying и не могу найти правильный ответ.
Возьмите два класса: Shape и Square . Квадрат определяется как:
@interface Square : Shape
Ничего удивительного. Каждый класс имеет одно свойство , Shape имеет int "стороны", а Square имеет int "width". Методы copyWithZone:
показаны ниже:
Shape
- (id)copyWithZone:(NSZone *)zone {
Shape *s = [[Shape alloc] init];
s.sides = self.sides;
return s;
}
Square
- (id)copyWithZone:(NSZone *)zone {
Square *s = (Square *)[super copyWithZone:zone];
s.width = self.width;
return s;
}
Глядя на документацию, кажется, что это «правильный» способ делать что-то.
Это не так.
Если бы вы попытались установить / получить доступ к свойству ширины Square, возвращенному методом copyWithZone:
, произойдет сбой с ошибкой, аналогичной приведенной ниже:
2010-12-17 11:55:35.441 Hierarchy[22617:a0f] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Shape setWidth:]: unrecognized selector sent to instance 0x10010c970'
Вызов [super copyWithZone: zone];
в методе Square фактически возвращает форму. Это чудо, что вам даже разрешено устанавливать свойство ширины в этом методе.
Как уже было сказано, как можно реализовать NSCopying для подклассов таким образом, что не делает их ответственными для копирования переменных своего суперкласса?