点表示法起初可能会有点误导。
二传手
在您在此处发布的行中
self.scale = scale;
您没有分配给局部变量。实际上,您将消息发送-setScale:
到self
. 这条线相当于
[self setScale:scale];
由于您是-setScale:
从内部调用的-setScale:
,因此您将获得这种无限递归。
您需要做的是在您的 setter 中设置一个实例变量(而不是从内部调用您的 setter)。通常,只要写
@property (nonatomic) CGFloat scale;
您已经创建了一个实例变量_scale
。 但是,由于您还覆盖了-scale
和-setScale:
,因此不会创建此实例变量。因此,您需要自己添加实例变量。在您的班级声明@interface
中(或者,在班级扩展 @interface
中)
//If adding the instance variable to the class declaration:
@interface MyClass : Superclass
{
//....
CGFloat _scale;
}
//....
@end
完成此操作后,将行更改为
_scale = scale;
吸气剂
您还发布了另外两条有问题的行,它们在 getter 中。第一个是
return self.scale;
里面- (CGFloat)scale
。与以前类似,这个点符号并不意味着你可能认为它的意思。事实上,这意味着
return [self scale];
和以前一样,这会导致无限递归。第二个是
if (!self.scale) {
出于同样的原因,这是一个问题:表达式self.scale
, 在评估时是 [self scale]。同样,这会导致无限递归。解决这两个问题的方法是self.scale
用_scale
这个 getter 代替:
- (CGFloat)scale
{
if (!_scale) {//Since CGFloat is not an object, this means <<if (_scale == 0) {>>
return DEFAULT_SCALE;
} else {
return _scale
}
}
更好的方法
你在这里做的工作比你真正应该做的要多得多。最好利用您的初始化程序:
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
{
self.scale = DEFAULT_SCALE;
}
}
这将保证如果scale
未设置,它将返回DEFAULT_SCALE
. 这使您可以完全消除吸气剂(因此,消除@synthesize
)。由于您-setNeedsDisplay
在 setter 中调用,因此您仍然需要它。
- (void)setScale:(CGFloat)scale
{
if (_scale != scale) {
_scale = scale;
[self setNeedsDisplay];
}
}