objective-c - Objective C 习语 - 属性、ivars 和 needsDisplay

标签 objective-c properties uikit ivar synthesize

这是我经常遇到的一种情况,样板代码已经够浪费了,而且我确定我不能成为唯一的这种情况。这是单向的,有没有更好的方法,还是我每次都必须这样做?

@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

现在这引发了一个编译警告,我没有 setter/getter ,要摆脱我可以添加的 setter/getter

- (CGFloat)insetMargin {
    return _insetMargin;
}

但是现在,它提示我没有 ivar(因为定义的 getter 和 setter 意味着没有为我创建一个),所以我需要添加

@interface SomeUIElement () {
    CGFloat _insetMargin;
}

这意味着我们要在属性更改时强制显示更新的开销很大。

是否有 (a) 某种方式告诉 ObjC 我确实打算它为我创建 getter 和 ivar,因此我只需要编写 setter,或者 (b) 一种更好的方式来请求显示更新,当与视觉外观变化相关的属性?

Apple 的 SDK 如何做到这一点(我假设我没有错过某种查看方式,比如 UILabel 源代码)?

最佳答案

如果属性声明为非原子的,您可以获得“部分综合”:

@property (nonatomic) CGFloat insetMargin;

默认(未知原因)是atomic。为了实现这种原子性,两个访问器都必须使用相同的锁定机制。但是,当方法被合成时,该机制不会暴露。因此,您必须要么实现两个访问器并创建您自己的锁,要么让编译器执行这两个操作并使用它的锁。

但是,如果属性不是原子的,您可以显式实现这三个元素的任意组合:ivar、setter 或 getter,编译器将处理其余部分。如果您想更改默认值的 ivar 名称(当前是带有前置下划线的属性名称),您还需要一个显式的 @synthesize

关于objective-c - Objective C 习语 - 属性、ivars 和 needsDisplay,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18028192/

相关文章:

NHibernate:找出属性是否映射到字段

ios - 电影播放器​​控件可见/隐藏时的通知?

ios - Swift:UITableViewCell 中的像素化文本

iphone - 处理父 View 触摸

objective-c - 如何以编程方式阻止 Mac 进入休眠状态?

objective-c - 为什么我得到这个 : _cfurl: unrecognized selector

Java 属性文件验证

objective-c - 在 iOS 中加载大图像并通过 outlet 调整大小

objective-c - 将回调/闭包从 Objective C 转换为 Swift

excel - 获取 Excel 名称管理器定义的特定单元格的 'Name'