Cra*_*tis 22 xcode memory-management objective-c hierarchy nscopying
我有一个小类层次结构,我无法实现copyWithZone:
.我已经阅读了NSCopying文档,但我找不到正确的答案.
选择两个类:Shape和Square.Square定义为:
@interface Square : Shape
Run Code Online (Sandbox Code Playgroud)
这并不奇怪.每个类都有一个属性,Shape有一个"sides"int,而Square有一个"width"int.该copyWithZone:
方法被认为如下:
形状
- (id)copyWithZone:(NSZone *)zone {
Shape *s = [[Shape alloc] init];
s.sides = self.sides;
return s;
}
Run Code Online (Sandbox Code Playgroud)
广场
- (id)copyWithZone:(NSZone *)zone {
Square *s = (Square *)[super copyWithZone:zone];
s.width = self.width;
return s;
}
Run Code Online (Sandbox Code Playgroud)
看一下文档,这似乎是做事的"正确"方式.
它不是.
如果您尝试设置/访问copyWithZone:
方法返回的Square的width属性,它将失败,并出现类似于下面的错误:
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'
Run Code Online (Sandbox Code Playgroud)
调用[super copyWithZone:zone];
Square方法实际上返回一个Shape.你甚至可以在该方法中设置width属性,这是一个奇迹.
话虽如此,如何以不使其负责复制其超类变量的方式实现子类的NSCopying?
Cra*_*tis 48
在询问之后你意识到的其中一件事......
copyWithZone:
超类(Shape)中的实现不应该假设它是一个Shape.因此,正如我上面提到的那样,而不是错误的方式:
- (id)copyWithZone:(NSZone *)zone {
Shape *s = [[Shape allocWithZone:zone] init];
s.sides = self.sides;
return s;
}
Run Code Online (Sandbox Code Playgroud)
您应该使用:
- (id)copyWithZone:(NSZone *)zone {
Shape *s = [[[self class] allocWithZone:zone] init]; // <-- NOTE CHANGE
s.sides = self.sides;
return s;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6350 次 |
最近记录: |