初始化这些变量时使用self.variable和_variable之间的区别

时间:2014-02-18 04:49:31

标签: objective-c declared-property

我知道实例变量和属性。我经常看到人们像这样初始化UILabel

self.label = [[UILabel alloc] init]; //and 
_label = [[UILabel alloc] init];

那么,使用self.label_label设置对象有什么区别?

4 个答案:

答案 0 :(得分:2)

区别很简单:使用self.label = [[UILabel alloc] init]实际上会调用方法[self setLabel:[[UILabel alloc] init]],使用_label = [[UILabel alloc] init]会直接将值分配给实例变量。

实际上,这意味着使用点语法通常是最好的,因为调用的方法可能会为你处理很多东西,包括:

  • 内存管理:例如,如果声明属性为“strong”或“retain”的属性,则调用的方法应保留指定的对象。
  • 键值编码通知:对于属性,类可能是key-value coding compliant,这意味着调用的方法将通知对观察者对象的更改。

为什么不使用点语法?有两个可能的原因:

  • 避免副作用:一个好的做法是不在初始化方法中使用点语法。这是因为我们想要分配值,但出于安全原因不希望调用方法的其他副作用。
  • 性能:这可能很少见,但是您可能尝试实现高性能的方法并直接使用实例变量可以节省调用方法的成本。

如果您想了解更多信息,我建议您阅读this iOS指南,其中详细介绍了我在此提及的想法。

答案 1 :(得分:1)

区别在于:

_variable的名称是实例变量。

self.variable正在对象上调用getter方法。

在您的示例中,实例变量是自动生成的,您也不需要合成属性。

如果您不使用ARC,那么您的示例中真正重要的区别就会发挥作用 -

如果您使用retain或strong标记属性,

self.variable将为您保留一个对象_variable根本不解决内存管理问题

答案 2 :(得分:0)

在您的示例中,self.label会在self上调用getter方法'label' - 这相当于调用[self label]_label是类实例属性的后备存储 - 即实例变量,与直接访问标准变量没有什么不同。它没有缠绕的getter方法。

差异非常非常重要,因为您可以覆盖属性的getter / setter方法。您可能希望这样做,例如,如果您希望将某些行为更改与变量的状态更改捆绑在一起。调用getter或setter可以保持这种行为。调用getter也会保留变量。

基本上,除非你知道为什么你更喜欢在任何特定情况下加入_label课程,否则坚持使用getter self.label。您可能希望使用_label的一种情况是在初始化期间,您需要设置一个快乐的默认w / o行为,这可能是getter带来的。

答案 3 :(得分:0)

不同之处在于使用_label直接访问实例变量(简称ivar),而使用self.label实际上是在调用[self setLabel:[[UILabel alloc] init]];

调用setLabel:方法可以执行其他操作,例如可能保留变量(取决于声明属性的方式),但也可以触发setLabel:方法中设置的其他副作用。这些副作用可能类似于数据验证,或者可能将该值同步到服务器。