導致更新的屬性
這個物件,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,允許你執行多個屬性集,只呼叫一個更新或旁路側 - 設定者造成的影響。