在子类的子类中实现 NSCopying
我有一个小的类层次结构,在实现 copyWithZone:
时遇到问题。我已阅读 NSCopying 文档,但找不到正确的答案。
参加两门课程:形状和正方形。 Square 的定义是:
@interface Square : Shape
这并不奇怪。每个类都有一个属性,Shape 有一个“sides” int,Square 有一个“width” int。 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;
}
查看文档,这似乎是“正确”的做事方式。
事实并非如此。
如果您尝试设置/访问 copyWithZone:
方法返回的 Square 的宽度属性,将会失败出现类似于以下错误:
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'
在 Square 方法中调用 [super copyWithZone:zone];
实际上返回一个 Shape。你甚至可以在该方法中设置宽度属性,这真是一个奇迹。
话虽如此,如何为子类实现 NSCopying,而不会让子类负责复制其超类的变量?
I have a small class hierarchy that I'm having trouble implementing copyWithZone:
for. I've read the NSCopying documentation, and I can't find the correct answer.
Take two classes: Shape and Square. Square is defined as:
@interface Square : Shape
No surprise there. Each class has one property, Shape has a "sides" int, and Square has a "width" int. The copyWithZone:
methods are seen below:
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;
}
Looking at the documentation, this seems to be the "right" way to do things.
It is not.
If you were to try to set/access the width property of a Square returned by the copyWithZone:
method, it would fail with an error similar to the one below:
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'
Calling [super copyWithZone:zone];
in the Square method actually returns a Shape. It's a miracle you're even allowed to set the width property in that method.
That having been said, how does one implement NSCopying for subclasses in a way that does not make them responsible for copying the variables of its superclass?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您在询问后立即意识到的事情之一...
超类 (Shape) 中
copyWithZone:
的实现不应该假设它是一个 Shape。因此,正如我上面提到的,您应该使用:
One of those things you realize right after asking...
The implementation of
copyWithZone:
in the superclass (Shape) shouldn't be assuming it's a Shape. So instead of the wrong way, as I mentioned above:You should instead use: