2013-07-29 36 views
1

正如标题所说:在分配和初始化它之前检查对象是否为零是否有必要或是否是一种好的做法?在分配对象之前需要检查nil

if (!_menuFetcher) { 
    _menuFetcher = [[MenuFetcher alloc] init]; 
    _menuFetcher.delegate = self; 

} 

我认为这就是所谓的懒加载权?

+0

最好是请检查是否对象是零访问它。使用将为您管理内存的属性访问器。 –

+0

因此,而不是使用实例变量_iVar,我应该使用self.iVar? :) – 7c9d6b001a87e497d6b96fbd4c6fdf

回答

2

延迟加载延迟对象的创建,直到您需要为止。 UIViewController通过它的视图来实现 - 创建一个视图层次结构需要花费大量的时间和内存,所以直到访问视图才能完成。您可以使用条件语句(如您所示的条件语句)来实现延迟加载。理想情况下,你会把它放在一个属性的访问器中,并在任何地方使用这个属性,所以你没有遍布整个地方的条件。

检查某个对象是否存在并不是坏习惯,但使用属性可以限制需要这样做的地方数量,这可以简化剩余的代码。

在分配之前不必总是检查是否存在某些东西 - 大部分时间您应该已经知道了。例如,在您的-init方法中,您知道还没有分配任何东西,您可以创建新对象所需的任何对象。

+0

谢谢。那么我需要为我所有的变量创建懒加载getters?然后使用self.iVar而不是_iVar? – 7c9d6b001a87e497d6b96fbd4c6fdf

+0

不,大多数时候你应该简单地设置你的ivars,如果你需要他们设置。使用属性而不是ivars通常是一个好主意。 – Caleb

+0

好的,非常感谢。 – 7c9d6b001a87e497d6b96fbd4c6fdf

1

是的,这基本上可以防止重新初始化已经初始化的东西。你应该一直这样做,除非你100%确定你没有重新初始化。但是,这不叫懒惰加载 - 有些不同。

例如,在表视图中加载图像时使用延迟加载。不是加载表格视图中的所有图像,只加载屏幕上可见的那些图像。这种方法更适合加载时间,性能和内存。

+0

这是懒加载,它可能也适用于表中的图像。它基本上意味着一个对象在第一次通过访问器访问时被加载。非常适合在表格视图单元中资源消耗图像。 –

+0

嗯,是的,你是对的。但我认为,当你说懒加载时,每个人都会想到加载图像和类似的表格:) –

1

通常你在getter方法中这样做。

假设你有一个特性:

@property (nonatomic, strong) MenuFetcher *menuFetcher; 

您在视图控制器使用说,那么你就可以实现该属性的吸气剂这样:

- (MenuFetcher *)menuFetcher 
{ 
    if (!_menuFetcher) { 
     _menuFetcher = [[MenuFetcher alloc] init]; 
     _menuFetcher.delegate = self; 
    } 
    return _menuFetcher; 
} 

你是正确的,这是一种惰性初始化(而不是加载)的形式 - 内存不分配,并且实例初始化直到它需要的地步。另外,你不需要有一个集中的初始化例程,也不需要担心对象的设置 - 如果它不存在,它会被创建 - 如果你通过将其设置回零来消除它,下一次某事想要某个类型的实例时,它会再次创建。所以在这方面它有点优雅和高效。

因此,实际上,您第一次尝试通过调用self.menuFetcher来读取该属性,如果尚未设置,您的getter将会注意到它为零,并为您创建并初始化它。一旦设置,属性不再为零,因此getter只是返回所持有的对象。

如果这适用于您正在编写的内容,请使用延迟初始化。唯一需要注意的是getters能够在懒惰初始化之外做其他事情 - 如果事情出错了,那些有“副作用”的getter可能会很痛苦。保持简单和专注。

0

惰性加载意味着“按需加载”,只执行时真正需要它的操作,它是这样的:

- (MenuFetcher *)instance{ 
    if (_menuFetcher == nil){ 
     _menuFetcher = [[MenuFetcher alloc] init]; 
    } 
    return _menuFetcher; 
} 
+0

几乎:-)你可能想要返回_menuFetcher或检查并将其分配给_ivar。 –

+0

哈哈,在与客户长时间争吵后感到头疼:S – null

1

这要看情况。

如果你只需要实例化一个新的对象,那么就不需要检查零。

分配对象之前不需要检查零。一点也不。

但是,这是一个相当不错的和广泛传播的模式,你在使用对象之前检查零。如果参考文献是零,那么您可以“随时”创建它。你必须在下面的代码中看到它(在这里或在调用者中)。有_menuFetcher将以某种方式使用。 (至少大部分probabyl) 或者这是一种可以在视图控制器中多次调用的方法,如viewWillAppear。你可能有很好的理由不要早先实例化和初始化对象,并且只能对对象进行一次实例化。在该方法的下一次调用中,您只需重新使用之前创建的对象。

(我的意思是在评论第一写这篇文章,不是一个答案,但它成为长的评论。)

相关问题