导致更新的属性
这个对象,Shape
有一个属性 image
,取决于 numberOfSides
和 sideWidth
。如果设置了其中任何一个,则必须重新计算 image
。但重新计算可能很长,只需要设置两个属性就可以完成一次,因此 Shape
提供了一种设置两个属性并且只重新计算一次的方法。这是通过直接设置属性 ivars 来完成的。
在 Shape.h
@interface Shape {
NSUInteger numberOfSides;
CGFloat sideWidth;
UIImage * image;
}
// Initializer that takes initial values for the properties.
- (instancetype)initWithNumberOfSides:(NSUInteger)numberOfSides withWidth:(CGFloat)width;
// Method that allows to set both properties in once call.
// This is useful if setting these properties has expensive side-effects.
// Using a method to set both values at once allows you to have the side-
// effect executed only once.
- (void)setNumberOfSides:(NSUInteger)numberOfSides andWidth:(CGFloat)width;
// Properties using default attributes.
@property NSUInteger numberOfSides;
@property CGFloat sideWidth;
// Property using explicit attributes.
@property(strong, readonly) UIImage * image;
@end
在 Shape.m
@implementation AnObject
// The variable name of a property that is auto-generated by the compiler
// defaults to being the property name prefixed with an underscore, for
// example "_propertyName". You can change this default variable name using
// the following statement:
// @synthesize propertyName = customVariableName;
- (id)initWithNumberOfSides:(NSUInteger)numberOfSides withWidth:(CGFloat)width {
if ((self = [self init])) {
[self setNumberOfSides:numberOfSides andWidth:width];
}
return self;
}
- (void)setNumberOfSides:(NSUInteger)numberOfSides {
_numberOfSides = numberOfSides;
[self updateImage];
}
- (void)setSideWidth:(CGFloat)sideWidth {
_sideWidth = sideWidth;
[self updateImage];
}
- (void)setNumberOfSides:(NSUInteger)numberOfSides andWidth:(CGFloat)sideWidth {
_numberOfSides = numberOfSides;
_sideWidth = sideWidth;
[self updateImage];
}
// Method that does some post-processing once either of the properties has
// been updated.
- (void)updateImage {
...
}
@end
当属性被分配给(使用 object.property = value
)时,调用 setter 方法 setProperty:
。这个 setter,即使由 @synthesize
提供,也可以被覆盖,就像在这种情况下 numberOfSides
和 sideWidth
一样。但是,如果你直接设置属性的 ivar(如果对象是 self 或 object->property
,则通过 property
),它不会调用 getter 或 setter,允许你执行多个属性集,只调用一个更新或旁路侧 - 设定者造成的影响。