在Objective-C中,如何正确实现可能为零的属性的惰性求值?
通常的做法如下所示,但是对于可能为零的属性它不能正常工作 - 它们的初始化不会只执行一次。
@interface LZClass: NSObject
@property (strong, readonly) NSString * lazyProp;
@end
@implementation LZClass
@synthesize lazyProp = _lazyProp;
- (NSString *)lazyProp {
if (_lazyProp == nil) {
_lazyProp = <Some Calculation>;
}
return _lazyProp
}
@end
答案 0 :(得分:-3)
更新:这个答案是不安全的。请参阅下面的Yan的评论。离开这里,所以有相同想法的人可以提防。
使用dispatch_once
代替检查nil。
@interface LZClass: NSObject {
dispatch_once_t _onceToken;
}
@property (strong, readonly) NSString * lazyProp;
@end
@implementation LZClass
@synthesize lazyProp = _lazyProp;
- (NSString *)lazyProp {
dispatch_once(&_onceToken, ^{
_lazyProp = <Some Calculation>;
}
return _lazyProp
}
@end
这也具有线程安全的优点。尝试在初始化块已被执行时读取属性的线程将阻塞,并在初始化块返回后继续。因此,保证在所有线程中返回正确的结果。
另外要注意:dispatch_once
的标准代码段定义了一个静态onceToken
,它在这里无法正常工作;初始化块仅对该类的第一个对象执行。