【问题标题】:Difference between using self.variable and _variable when init these variables [duplicate]初始化这些变量时使用self.variable和_variable之间的区别[重复]
【发布时间】:2014-03-17 15:59:30
【问题描述】:

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

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

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

【问题讨论】:

  • 它只是一个约定,表示它是私有变量。我相信在概念上是一样的。

标签: objective-c declared-property


【解决方案1】:

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

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

  • 内存管理:例如,如果您声明一个属性为“strong”或“retain”的属性,则调用的方法应该保留分配的对象。
  • Key-Value Coding 通知: 属性的类可能是key-value coding compliant,这意味着调用的方法将通知观察者对象的更改。

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

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      不同的是:

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

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

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

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

      self.variable 会为你保留一个对象,如果你用retain 或strong 标记属性_variable 根本不解决内存管理问题

      【讨论】:

      • Xcode 在后台合成了一个 @property xxxx 和一个名为 _xxxx 的 ivar。所以你看不出来,_xxxxx 是实例变量。
      【解决方案4】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-05-27
        • 1970-01-01
        • 1970-01-01
        • 2013-02-10
        • 2014-07-26
        • 1970-01-01
        • 2013-12-02
        相关资源
        最近更新 更多