Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
objective-c属性-getter和setter_Objective C_Ios_Uiview_Getter Setter - Fatal编程技术网

objective-c属性-getter和setter

objective-c属性-getter和setter,objective-c,ios,uiview,getter-setter,Objective C,Ios,Uiview,Getter Setter,在UIView子类中,我具有以下属性: @property (nonatomic) CGFloat scale; #define DEFAULT_SCALE 0.90 还有这个能手和能手: -(CGFloat)scale { if (!self.scale) { return DEFAULT_SCALE; }else{ return self.scale; } } -(void)setScale:(CGFloat)scale {

在UIView子类中,我具有以下属性:

@property (nonatomic) CGFloat scale;

#define DEFAULT_SCALE 0.90
还有这个能手和能手:

-(CGFloat)scale
{
    if (!self.scale) {
        return DEFAULT_SCALE;
    }else{
        return self.scale;
    }
}

-(void)setScale:(CGFloat)scale
{
    if (scale != self.scale) {
        self.scale = scale;
        [self setNeedsDisplay];
    }

}

这是不正确的,因为例如,检查getter中的self.scale会导致无限循环。编写getter和setter的正确方法是什么,这样我就不会得到无限循环?

您应该能够通过
\u scale
直接访问ivar。然后,您的getter/setter将如下所示:

更新:正如@Wattson 12在下面的评论中指出的,您需要在实现中添加一个
@synthesis

@synthesize scale = _scale;

-(CGFloat)scale
{
    if (!_scale) {
        return DEFAULT_SCALE;
    }else{
        return _scale;
    }
}

-(void)setScale:(CGFloat)scale
{
    if (scale != _scale) {
        _scale = scale;
        [self setNeedsDisplay];
    }

}

二传手 在你贴在这里的那条线上

self.scale = scale;
您没有分配给局部变量。实际上,您正在将消息
-setScale:
发送到
self
。这条线相当于

[self setScale:scale];
由于您正在从
-setScale:
内部调用
-setScale:
,因此得到了这个无限递归

您需要做的是在setter中设置一个实例变量(而不是从setter内部调用它)。通常,只是通过写作

@property (nonatomic) CGFloat scale;
您已经创建了一个实例变量
\u scale
但是,因为您同时覆盖了
-scale
-setScale:
,所以不会创建此实例变量。因此,您需要自己添加实例变量。在类的声明
@接口中
(或者,在
@接口中

完成此操作后,将行更改为

_scale = scale;
吸气剂 您还发布了另外两个有问题的行,它们位于getter中。首先是

return self.scale;
内部
-(CGFloat)刻度
。与之前类似,此点符号的含义与您可能认为的不同。事实上,这意味着

return [self scale];
和以前一样,这会导致无限递归。二是

if (!self.scale) {
这是一个问题,原因相同:表达式
self.scale
,在计算时为[self scale]。同样,这会导致无限递归。解决这两个问题的方法是用
\u scale
替换
self.scale
,这样您就有了这个getter:

- (CGFloat)scale
{
    if (!_scale) {//Since CGFloat is not an object, this means <<if (_scale == 0) {>>
        return DEFAULT_SCALE;
    } else {
        return _scale
    }
}
这将保证如果未设置
scale
,它将返回
默认值\u scale
。这允许您完全消除getter(因此,
@synthesis
)。由于您正在setter中调用
-setNeedsDisplay
,因此仍然需要它

- (void)setScale:(CGFloat)scale
{
    if (_scale != scale) {
        _scale = scale;
        [self setNeedsDisplay];
    }
}

嗯,我可以想出三种方法来做到这一点,并且要注意

@interface someClass
{
    BOOL useCustomScale;
}
@property float scale;
@end
@implimentation someClass
-(float)scale
{
    if(useCustomScale)
    {return scale;}
    return defaultScale;
}
-(void) setScale: (float)someScale
{
    useCustomScale = YES;
    scale = someScale
}
否则,您可以使用NSNumber来支持刻度值…
否则,您可以将比例初始化为-1,并在setter中使其成为非法值。

在测试中使用0通常是一件非常糟糕的事情,因为您可能非常希望0是有效值。

我得到了“使用未声明的标识符'\u scale'”。您是否在属性中使用了
@synthesis
?您是否在界面中创建了
scale
变量?如果您同时覆盖setter和getter,则无法获得自动合成功能,您将需要添加@synthesis scale=\u scale;是的,这就是问题所在。我通常不需要合成,因为Xcode会自动合成。如果覆盖getter和setter,就不需要@synthesis。只需添加您自己的ivar,并让方法使用ivar.+1进行解释。这就是我的想法,但我不知道编写自己的getter/setter意味着必须合成属性。@soleil我强烈建议您尝试一下我在标题“更好的方法”下所写的内容。您所做的工作比实际需要的要多得多。为什么只删除getter会消除@synthetic?@soleil您只需要
@synthetic
,因为您同时覆盖了setter和getter。消除其中一个覆盖后,将自动为您创建
\u scale
实例变量。
- (void)setScale:(CGFloat)scale
{
    if (_scale != scale) {
        _scale = scale;
        [self setNeedsDisplay];
    }
}
@interface someClass
{
    BOOL useCustomScale;
}
@property float scale;
@end
@implimentation someClass
-(float)scale
{
    if(useCustomScale)
    {return scale;}
    return defaultScale;
}
-(void) setScale: (float)someScale
{
    useCustomScale = YES;
    scale = someScale
}