ドット表記は、最初は少し誤解を招く可能性があります。
セッター
あなたがここに投稿した行で
self.scale = scale;
ローカル変数に割り当てていません。実際、メッセージ-setScale:
をに送信していますself
。この行は、
[self setScale:scale];
-setScale:
内から呼び出しているので-setScale:
、この無限の再帰が発生します。
あなたがする必要があるのは、(それ自体の中からあなたのセッターを呼び出すのではなく)あなたのセッターにインスタンス変数を設定することです。通常、書くだけで
@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;
ゲッター
あなたが投稿した他の2つの問題のある行があります。これらはゲッターにあります。最初は
return self.scale;
中- (CGFloat)scale
。以前と同様に、このドット表記は、あなたがそれが意味すると思うかもしれないことを意味するものではありません。実際、それは
return [self scale];
以前のように、これは無限の再帰を引き起こしています。2番目は
if (!self.scale) {
同じ理由で問題がありself.scale
ます。評価されたときの式は[自己スケール]です。繰り返しますが、これは無限の再帰を引き起こします。これらの両方の修正は、このゲッターself.scale
を残すことに置き換えることです。_scale
- (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
、それでも必要になります。
- (void)setScale:(CGFloat)scale
{
if (_scale != scale) {
_scale = scale;
[self setNeedsDisplay];
}
}