Objective-C语言导致更新的属性

示例

此对象Shape的属性image取决于numberOfSides和sideWidth。如果设置了其中一个,则image必须重新计算。但是重新计算可能很长,如果同时设置了两个属性,则只需要执行一次,因此Shape可以提供一种设置两个属性并且仅重新计算一次的方法。这是通过直接设置属性ivars来完成的。

在 Shape.h

@interface Shape {
    NSUInteger numberOfSides;
    CGFloat sideWidth;

    UIImage * image;
}

// 初始化程序,用于获取属性的初始值。
- (instancetype)initWithNumberOfSides:(NSUInteger)numberOfSides withWidth:(CGFloat)width;

// 允许在一次调用中设置两个属性的方法。
// 如果设置这些属性具有昂贵的副作用,这将很有用。
// 通过使用一种方法一次设置两个值,您可以
// 效果只执行一次。
- (void)setNumberOfSides:(NSUInteger)numberOfSides andWidth:(CGFloat)width;

// 使用默认属性的属性。
@property NSUInteger numberOfSides;
@property CGFloat sideWidth;

// 使用显式属性的属性。
@property(strong, readonly) UIImage * image;

@end

在 Shape.m

@implementation AnObject

// 由编译器自动生成的属性的变量名称
// 默认为以下划线为前缀的属性名称,例如
// example "_propertyName". You can change this default variable name using
// 以下语句:
// @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];
}

// 一旦两个属性中的任何一个具有
// 已更新。
- (void)updateImage {
    ...
}

@end

将属性分配给(使用object.property = value)时,将setProperty:调用setter方法。即使是由提供程序提供的@synthesize,此设置程序也可以被覆盖,就像在这种情况下,对于numberOfSides和sideWidth。但是,如果您直接设置属性的ivar(property如果对象是self或object->property,则它不设置),则它不会调用getter或setter,从而使您可以执行多个属性集之类的操作,这些属性集仅调用一个更新或绕过导致的副作用由二传手。