使用int属性延迟加载Objective-C类

时间:2013-12-18 20:07:28

标签: objective-c class properties int null

我在以下某个类中使用以下内容作为属性的getter:

- (NSString *)version
{
    if (_version == nil) {
        _version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
    }
    return _version;
}

这很有效。但是,当我为int属性尝试相同时,我显然会得到一个错误,因为int永远不会为零。围绕这个最好的方法是什么?

- (int)numberOfDays
{
    if (_numberOfDays == nil) {
        // relatively memory intense calculation that works out numberOfDays:
        _numberOfDays = X;
    }    
    return _numberOfDays;
}

5 个答案:

答案 0 :(得分:2)

首先,如果可能,建议不要使用int Objective-C。如果需要使用原始整数类型,则应使用NSInteger。 NSInteger的大小是在编译时根据为其构建的体系结构确定的。 int是一个静态大小,不会因不同的体系结构而变宽。只要注意就可以使用它。

使用NSInteger,你仍然面临同样的问题,它不能是零。因此,您应该将您的属性设为NSNumber,您可以使用[NSNumber numberWithInteger:anInteger];计算结果。这样,您可以对您的财产进行零检查,只进行一次计算以创建NSNumber

答案 1 :(得分:1)

使用GCD。

static dispatch_once_t tok;
dispatch_once(&tok, ^{ memory_intensive_computation(); });

不,不要使用GCD,我错过了重点。在实例方法中,您希望将信息绑定到每个实例,因此使用静态调度令牌是不合适的。也许你应该坚持使用“布尔标志作为实例变量”方法。

或者,您可以将int初始化为已知超出其有效范围的值(例如,我认为numberOfDays永远不会为负)并将其用作条件用于执行计算。

答案 2 :(得分:1)

使用NSNumber存储int值。

- (int)numberOfDays
{
    if (_numberOfDays == nil) {
        // relatively memory intense calculation that works out numberOfDays:
        _numberOfDays = @(X);
    }    
    return [_numberOfDays intValue];
}

答案 3 :(得分:1)

添加另一个布尔实例变量_numberOfDaysCalculated

是一个线程安全的版本
- (int)numberOfDays
{
    @synchronized(self) {
        if (!_numberOfDaysCalculated) {
            // relatively memory intense calculation that works out numberOfDays:
            _numberOfDays = X;
            _numberOfDaysCalculated = YES;
        }
    }    
    return _numberOfDays;
}

或者,如果属性的某个“无效”值,您可以使用它 作为“尚未计算”的标记。例如,如果numberOfDays的计算值必须为非负值,则可以在_numberOfDays = -1方法中初始化init, 然后在惰性getter方法中测试if (_numberOfDays == -1)

答案 4 :(得分:0)

我会使用_numberOfDays初始化-init中的NSNotFound并在getter中对其进行测试。