Objective-C/iPhone开发中的懒惰实例化

use*_*574 26 initialization properties objective-c alloc lazy-initialization

快速问题......我明白所有属性在Objective-C中以nil开头,并且向nil发送消息不起作用,因此必须使用[[Class alloc] init]初始化; 在向新创建的属性发送消息之前.但是,如果我不向此属性发送消息或者如果我使用self.property = some设置属性呢?在这些情况下我是否还需要分配init?此外,UI属性也是以nil开头的,例如您从故事板中拖出的UILabel属性?这些需要alloc init吗?

感谢所有回答的人

Jas*_*lin 39

Stunner很好地解释了不需要分配已经创建的init对象.

但如果它是一个不存在的对象,你将在哪里创建它?我提到的一个非常常见的模式,因为你在帖子中提到它,是懒惰的实例化.

所以你想要一个NSMutableArray属性.你可以在使用它之前用某种方法分配init,但是你必须担心"在我需要我的数组之前是否会调用该方法?" 或者"我是否会意外地再次呼叫它并重新初始化它."

因此,一个故障安全的地方是在财产的吸气剂.每次访问该属性时都会调用它.

.h
@property (nonatomic, strong) NSMutableArray* myArray;

.m
@synthesize myArray = _myArray;

- (NSMutableArray*)myArray
{
    if (!_myArray) {
        _myArray = [[NSMutableArray alloc] initWithCapacity:2];
    }
    return _myArray;
}
Run Code Online (Sandbox Code Playgroud)

每当你访问该属性时,它会说:"myArray是否存在?如果不存在,请创建它.如果存在,只需返回我拥有的内容."

此设计模式的另一个好处是,您不需要在需要之前创建资源,而不是一次性创建资源,例如,当您的视图控制器加载或您的应用程序启动时,这取决于要求,可能需要一些秒.

  • 很好的回应,但我不同意在getter中实例化ivars,因为这会使查询对象的存在变得不可行.相反,我建议你在setter中进行实例化,因为你确定你所设置的ivar是否不存在,你希望它存在以便它可以设置为一个值.因此,在调用setter时,永远不会有一个你不希望它存在的时间,而在调用getter时,情况并非总是如此. (4认同)

Kaa*_*glu 4

事实上,当您这样做时self.myProperty = [[Class alloc] init],您并没有初始化您的财产。相反,您正在初始化一个对象,并告诉您的属性(实际上是一个指针)指向该对象。因此,如果您已经有一个已分配和初始化的对象,则不必再次分配/初始化,您可以这样做self.myProperty = object

UI 属性不会以 nil 开头,这是因为当您在界面构建器中添加元素时,视图拥有您添加的元素,并且这些对象会自动为您初始化。这意味着如果您要创建 IBOutlet 并将它们连接到某些属性,则不必进行分配/初始化。

我希望这可以帮到你。