【问题标题】:How to lazily set BOOL property in Objective-C如何在 Objective-C 中懒惰地设置 BOOL 属性
【发布时间】:2023-03-14 11:20:01
【问题描述】:

我需要一个数据结构上的 BOOL 属性,表示数据库中某个对象的状态,并且我想懒惰地设置该属性——也就是说,我不想在需要之前 ping 数据库,并且只在那个时候设置属性(即我第一次得到它时)。

对于像 NSString 这样的东西,我会做一个像

这样的 getter
- (NSString *)myString {
    if (!_myString) {

        // ask db for value
        _myString = [value returned from db]

    }
    return _myString;
}

但在 Objective-C 中,BOOL 似乎默认为 NO——这意味着我永远不会知道该值是否实际上是 NO,或者我还没有得到它。我已经四处寻找,但我似乎无法弄清楚如何为这样的属性创建我想到的那种吸气剂。有什么建议?还是我错过了一些非常明显的东西?提前致谢。

【问题讨论】:

  • 你可以使用一个也可以存储真/假值的 NSNumber 而不是 bool,然后你可以测试 NSNumber 是否为 nil
  • 你也可以只使用一个初始化为 -1 的 int,然后你可以将它设置为 0 或 1,如果它是真或假,你可以知道它还没有被延迟加载,如果它 - 1
  • @Fonix 使用 int 是个好主意
  • 使用整数很好。您也可以只使用两个布尔值,一个用于保存值,另一个用于指示第一个是否有效/已被初始化。

标签: ios objective-c boolean getter-setter


【解决方案1】:

您可以在对象内部使用 NSNumber:

// .h
@interface Object : NSObject

@property (nonatomic, assign) BOOL myBool;

@end

//.m
@interface Object ()

@property (nonatomic, strong) NSNumber *myBoolFromDB;

@end

@implementation Object

- (BOOL) myBool {
    if (_myBoolFromDB == nil) {
        ...
    }
    return [_myBoolFromDB boolValue];
}

@end

【讨论】:

    【解决方案2】:

    如果您只需要进行一次初始化,并且每个类的实例不需要一次dispatch_once() 可能是一个不错的工具:

    - (BOOL)myBool {
        static dispatch_once_t once;
        dispatch_once(&once, ^{
            // initialize _myBool here
        });
        return _myBool;
    }
    

    从实际的角度来看,它与其他解决方案并没有太大的不同:您需要记住您是否已经初始化了状态不知何故,以及是否通过将状态存储在指针中来完成可以是 nil,或者在一个 int 中可以有一些“未初始化”的值,或者在一个静态的 once 变量中编码并没有太大区别。

    不过,我喜欢这种方法的地方在于,它清楚地传达了您的意图:您希望这件事仅在第一次调用 myBool 时发生。它还允许您将myBool 属性存储为BOOL,而不是您必须转换为BOOL 的其他类型,这再次更清楚地传达了您的意图。

    【讨论】:

    • 如果你不明白你在做什么,这是非常危险的。如果该类有多个实例,那么这将无法正常工作。该类只有一个 once 变量,而不是每个实例一个。因此,一旦在任何实例上调用了 -myBool,“在此处初始化 _myBool”代码将为该实例运行,然后不再运行,无论是该实例还是其他任何实例。
    • @KenThomases 完全同意!我可能在这里假设太多了。我会编辑以明确这一点。感谢您了解这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-23
    • 2013-08-19
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多