Question

Here's a situation I come across a lot, enough that the boilerplate code is wasteful and enough that I'm sure I can't be the only one. Is this unidiomatic, is there a better way, or do I just have to do it each time?

@interface SomeUIElement : UIView
@property CGFloat insetMargin; // <-- just an example of a UI parameter
@end

@implementation SomeElement
- (void)setInsetMargin:(CGFloat)insetMargin {
    _insetMargin = insetMargin;
    [self setNeedsDisplay]; // <-- the only thing that stops it being synthesized
}
@end

now this raises a compile warning, that I don't have a getter, to get rid of that I can add

- (CGFloat)insetMargin {
    return _insetMargin;
}

but now, it complains I don't have an ivar (because a defined getter and setter means one isn't created for me), so I need to add

@interface SomeUIElement () {
    CGFloat _insetMargin;
}

which means we're at a substantial overhead for just wanting to force a display update when a property changes.

Is there (a) some way to tell ObjC that I did intend it to create the getter and ivar for me, so I only need to write the setter, or (b) a better way to request a display update when a property related to the visual appearance changes?

How does Apple's SDKs do this (I'm assuming I haven't missed some way of viewing, say the UILabel source)?

Was it helpful?

Solution

You can get "partial synthesis" if the property is declared nonatomic:

@property (nonatomic) CGFloat insetMargin;

The default (for unknown reasons) is atomic. In order to implement that atomicity, both of the accessors have to use the same locking mechanism. That mechanism isn't exposed when the methods are synthesized, though. Therefore you have to either implement both accessors and create your own lock or let the compiler do both and use its lock.

If the property is not atomic, however, you can explicitly implement any combination of the three elements: ivar, setter, or getter, and the compiler will take care of the rest. If you want to change the name of the ivar from the default (currently the property name with a prepended underscore), you will also need an explicit @synthesize.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top