Point notation can be misleading at first.
Setter
In the line you posted here
self.scale = scale;
you are not assigning a local variable. In fact, you send the -setScale: message to self . This line is equivalent
[self setScale:scale]
Since you call -setScale: from -setScale: you get this infinite recursion.
What you need to do is set the instance variable in your setter (instead of invoking your setter from within itself). Usually just by writing
@property (nonatomic) CGFloat scale;
You have created the _scale instance _scale . However , since you also redefined both -scale and -setScale: this instance variable will not be created. Therefore, you will need to add the instance variable yourself. In the declaration of your @interface class (or, alternatively, in the extension of the @interface class )
After that, just change the line to
_scale = scale;
Getter
There are two other problematic lines that you posted, this is in the getter. First -
return self.scale;
inside - (CGFloat)scale . Just like before, this dotted notation does not mean what you think it means. It actually means
return [self scale];
As before, this causes infinite recursion. Second -
if (!self.scale) {
This is a problem for the same reason: the expression self.scale when evaluating [self scale]. Again, this leads to infinite recursion. The fix for both of them is to replace self.scale with _scale , leaving you with this recipient:
- (CGFloat)scale { if (!_scale) {//Since CGFloat is not an object, this means <<if (_scale == 0) {>> return DEFAULT_SCALE; } else { return _scale } }
The best way
You do a lot more work here than you should be. It would be much better to use your initializer:
- (id)initWithFrame:(NSRect)frame { self = [super initWithFrame:frame]; { self.scale = DEFAULT_SCALE; } }
This ensures that if scale not set, it will return DEFAULT_SCALE . This allows you to completely eliminate getter (and therefore @synthesize ). Since you call -setNeedsDisplay on the setter, you still need to.
- (void)setScale:(CGFloat)scale { if (_scale != scale) { _scale = scale; [self setNeedsDisplay]; } }