0

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

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

self.label那么,使用和_label设置对象有什么区别呢?

4

4 回答 4

2

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

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

  • 内存管理:例如,如果您声明一个具有“strong”或“retain”属性的属性,则调用的方法应该保留分配的对象。
  • 键值编码通知:可能类对属性是键值编码兼容的,这意味着调用的方法将通知观察者对象的更改。

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

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

如果你想了解更多,我推荐阅读这个iOS 指南,它更详细地描述了我在这里提到的想法。

于 2014-02-18T06:55:14.663 回答
1

不同之处在于:

带有的名称_variable是实例变量。

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

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

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

self.variable_variable如果您将属性标记为 retain 或 strong根本不会解决内存管理,将为您保留一个对象

于 2014-02-18T04:54:04.663 回答
0

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

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

于 2014-02-18T04:55:40.497 回答
0

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

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

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

于 2014-02-18T04:54:13.517 回答