这是我经常遇到的一种情况,足以使样板代码浪费而且我确信我不能成为唯一的代码。这是不同寻常的,是否有更好的方法,或者我每次都必须这样做?
@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
现在这引发了一个编译警告,我没有一个getter,摆脱我可以添加
- (CGFloat)insetMargin {
return _insetMargin;
}
但现在,它抱怨我没有ivar(因为定义的getter和setter意味着没有为我创建),所以我需要添加
@interface SomeUIElement () {
CGFloat _insetMargin;
}
这意味着当属性发生变化时,我们只是想要强制显示更新。
是否有某种方式告诉ObjC我确实打算为我创建getter和ivar,所以我只需要编写setter,或者(b)更好的方式来请求显示更新视觉外观变化相关的属性?
Apple的SDK如何做到这一点(我假设我没有错过任何观看方式,比如UILabel来源)?
答案 0 :(得分:5)
如果声明属性为非原子属性,则可以获得“部分合成”:
@property (nonatomic) CGFloat insetMargin;
默认(出于未知原因)是 atomic 。为了实现该原子性,两个访问器都必须使用相同的锁定机制。但是,当合成方法时,不会暴露该机制。因此,您必须实现两个访问器并创建自己的锁,或让编译器执行这两个操作并使用其锁定。
但是,如果属性不是原子属性,则可以显式实现三个元素的任意组合:ivar,setter或getter,编译器将负责其余部分。如果您想要从默认值更改ivar的名称(当前是带有前置下划线的属性名称),您还需要一个明确的@synthesize
。