Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

objective-c properties - getters and setters

In a UIView subclass I have this property:

@property (nonatomic) CGFloat scale;

#define DEFAULT_SCALE 0.90

and this getter and setter:

-(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];
    }

}

This isn't correct, because for example checking self.scale in the getter causes an infinite loop. What is the proper way to write the getter and setter so that I don't get infinite looping?

like image 918
soleil Avatar asked Oct 31 '12 16:10

soleil


People also ask

What are Objective C properties?

The goal of the @property directive is to configure how an object can be exposed. If you intend to use a variable inside the class and do not need to expose it to outside classes, then you do not need to define a property for it. Properties are basically the accessor methods.

What is @synthesize in Objective C?

@synthesize tells the compiler to take care of the accessor methods creation i.e it will generate the methods based on property description. It will also generate an instance variable to be used which you can specify as above, as a convention it starts with _(underscore)+propertyName.

What is getter and setter in IOS?

A getter method is used to perform a computation when requested. A setter method is an optional method. It can be used to modify a related property.

What is getter and setter in Swift?

Setters and getters in Swift apply to computed properties/variables. These properties/variables are not actually stored in memory, but rather computed based on the value of stored properties/variables. See Apple's Swift documentation on the subject: Swift Variable Declarations.


2 Answers

You should be able to access the ivar directly as _scale. Your getter/setter would then look like:

Update: As @wattson12 points out in the comments below you will need to add an @synthesize to your implementation.

@synthesize scale = _scale;

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

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

}
like image 131
mttrb Avatar answered Oct 14 '22 20:10

mttrb


well I can think of about 3 ways to do this and be 0 aware.

@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
}

else you could use an NSNumber for backing the scale value...
else you could initialize the scale to -1 and make that an illegal value in the setter.
0 is typically a very bad thing to use for your test because you may very well want 0 to be valid value.

like image 45
Grady Player Avatar answered Oct 14 '22 21:10

Grady Player