26

我听说 iOS 中对象的惰性实例化很常见,但是我不确定什么时候应该使用它?有人可以简要解释一下我什么时候应该使用惰性实例化,什么时候应该在 init 方法中初始化我的属性?

我对延迟实例化的担忧是它需要大量代码(与仅在 init 方法中编写所有代码相比),特别是如果您有多个要初始化的属性。

4

4 回答 4

18

To elaborate on my comment. Sometimes this technique is good if you have an object that only needs to be configured once and has some configuration involved that you don't want to clutter your init method.

- (UIView *)myRoundedView;
{
    if (!_myRoundedView) {
        _myRoundedView = [[UIView alloc] initWithFrame:<#some frame#>];
        _myRoundedView.layer.cornerRadius = 10.f;
        _myRoundedView.backgroundColor    = [UIColor colorWithWhite:0.f alpha:0.6f];
        _myRoundedView.autoresizingMask   = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    }
    return _myRoundedView;
}

It's a pretty contrived example but you can start to see the merit. Methods should be like classes and do one thing well. This method happens to return the roundedView I want. If I slapped this code into the init method then the init method would now have to know the nitty gritty details of how to instantiate and configure this view and any other objects that I slap in there.

于 2012-05-24T15:22:30.557 回答
13

这在您拥有可能占用大量内存的对象的情况下非常有用,因此您可以避免在容器类初始化时初始化所有这些昂贵的对象。延迟初始化可以在几种情况下保留内存消耗......

但是很明显,如果所有对象都需要在容器对象初始化之后或之后立即进行初始化,则延迟初始化没有任何意义,应该使用标准的构造函数初始化。

应该使用延迟初始化,以防在所有类工作流程中永远无法初始化的类中有可选对象。

于 2012-05-24T14:48:27.677 回答
11

与任何技术一样,没有一个单一的、千篇一律的规则来告诉您何时懒惰地实例化某些东西。我认为好的建议是对实例化昂贵的东西使用惰性实例化。如果某事需要进行大量的磁盘或网络访问,或者需要大量的 CPU 时间来设置,则最好将这项工作推迟到实际需要(或在后台进行)。特别是对于用户可能会或可能不会使用的功能,在(或类似的)设置上浪费大量时间是没有意义的-init,这样做会导致您的应用程序对用户感到迟钝。

话虽如此,您应该避免过早的优化。不要花很多时间编写复杂的代码来帮助提高性能,直到您以明显的方式完成事情,发现性能问题,并分析您的代码以彻底理解问题。完成后,您可以开始进行更改以改进事情。

于 2012-05-24T14:47:36.673 回答
3

不仅是为了内存和性能,看看这个,这是另一个例子:

- (NSArray *)validElements{
    if (!_validElements) {
        _validElements = [[NSArray alloc] initWithObjects:
                          @"mystuff",@"generaldescription",@"title",@"autor",
                          @"version",@"date",@"context",@"operatingsystem",@"kindofdevice",
                          @"deviceversion",@"rule",@"daytime",@"time",@"location",@"deviceheading",
                          @"region",@"language",nil];
    }
    return _validElements;
}

您可以使用惰性实例化来进行自定义初始化或特殊配置,是的,这也有利于内存和性能。

于 2012-10-24T14:39:10.003 回答