首先,Cocoa的命名约定会将getter命名为-width
,而不是-getWidth
。 "Get"一词用于填充传递的参数:
- (void) getWidth:(CGFloat *)outWidth
{
if (outWidth) *outWidth = _width;
}
话虽如此,回到您最初的问题:
在@property
和@synthesize
之前的旧时代,我们必须手动编写访问器,就像您上面所做的那样。
然而,还有其他情况下需要手动编写访问器。
其中一个常见的情况是延迟初始化直到需要值。例如,假设有一张需要较长时间生成的图像。每次修改会改变该图像的属性时,您不希望立即重新绘制该图像。相反,您可以推迟绘制,直到下一次有人要求绘制时再进行绘制:
- (UIImage *) imageThatTakesAwhileToGenerate
{
if (!_imageThatTakesAwhileToGenerate) {
}
return _imageThatTakesAwhileToGenerate;
}
- (void) setColorOfImage:(UIColor *)color
{
if (_color != color) {
[_color release];
_color = [color retain];
[_imageThatTakesAwhileToGenerate release];
_imageThatTakesAwhileToGenerate = nil;
}
}
另一个用途是将访问器/修改器的实现转发到另一个类。例如,UIView
将其许多属性转发到后备的 CALayer
:
- (CGRect) bounds { return [[self layer] bounds]; }
- (void) setBounds:(CGRect)bounds { [[self layer] setBounds:bounds]; }
- (void) setHidden:(BOOL)hidden { [[self layer] setHidden:hidden]; }
- (BOOL) isHidden { return [[self layer] isHidden]; }
- (void) setClipsToBounds:(BOOL)clipsToBounds { [[self layer] setMasksToBounds:clipsToBounds]; }
- (BOOL) clipsToBounds { return [[self layer] masksToBounds]; }
更新问者的最新信息:
从你的更新看来,这段代码要么试图使用NSUserDefaults持久化width的值,要么试图允许用户指定一个自定义值来覆盖所有返回的宽度。如果是后者,你的示例代码是可以的(尽管我会限制这种做法,因为它可能会使新手感到困惑)。
如果是前者,你需要在setter方法中从NSUserDefaults中加载一次该值,并将新值保存回NSUserDefaults。例如:
static NSString * const sUserWidthKey = @"USER_WIDTH";
@implementation Foo {
CGFloat _width;
BOOL _isWidthIvarTheSameAsTruthValue;
}
@synthesize width = _width;
- (CGFloat) width
{
if (!_isWidthIvarTheSameAsTruthValue) {
NSNumber *userWidth = [[NSUserDefaults standardUserDefaults] objectForKey:sUserWidthKey];
if (userWidth != nil) _width = [NSNumber doubleValue];
_isWidthIvarTheSameAsTruthValue = YES;
}
return _width;
}
- (void) setWidth:(CGFloat)newWidth
{
if (_width != newWidth) {
_width = newWidth;
NSNumber *userWidthNumber = [NSNumber numberWithDouble:_width];
[[NSUserDefaults standardUserDefaults] setObject:userWidthNumber forKey:sUserWidthKey];
_isWidthIvarTheSameAsTruthValue = YES;
}
}
@end
_width实例变量被用作缓存。事实上,真实数据存储在NSUserDefaults中。
注意:我在这个示例中使用NSUserDefaults,因为你在你的示例中也使用了它。但在实际应用中,我更喜欢不将NSUserDefaults与我的访问器混合使用 ;)