如何在 Objective-C 中懒惰地设置 BOOL 属性
Posted
技术标签:
【中文标题】如何在 Objective-C 中懒惰地设置 BOOL 属性【英文标题】:How to lazily set BOOL property in Objective-C 【发布时间】:2015-08-06 13:49:19 【问题描述】:我需要一个数据结构上的 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 是个好主意 使用整数很好。您也可以只使用两个布尔值,一个用于保存值,另一个用于指示第一个是否有效/已被初始化。 【参考方案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 完全同意!我可能在这里假设太多了。我会编辑以明确这一点。感谢您了解这一点。以上是关于如何在 Objective-C 中懒惰地设置 BOOL 属性的主要内容,如果未能解决你的问题,请参考以下文章
RxSwift:如何使用 shareReplay 懒惰地获取订阅