【问题标题】:How to implement lazy evaluation of objective-C property which may be nil?如何实现可能为零的objective-C属性的惰性评估?
【发布时间】:2014-03-24 15:48:33
【问题描述】:

在 Objective-C 中,如何正确实现对可能为 nil 的属性的惰性求值?

下面演示了通常的做法,但它不适用于可能为 nil 的属性 - 它们的初始化不会只执行一次。

@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

【问题讨论】:

  • 使用 dispatch_once,或者干脆有一个单独的布尔变量。

标签: objective-c thread-safety lazy-loading lazy-evaluation lazy-initialization


【解决方案1】:

更新:这个答案不安全。请参阅下面的 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 的标准代码 sn-p 定义了一个静态的 onceToken,它在这里不能正常工作;初始化块只会针对类的第一个对象执行。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-08
  • 2015-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
相关资源
最近更新 更多