【问题标题】:Objects creation and instantiation in objective-cObjective-c 中的对象创建和实例化
【发布时间】:2011-07-06 12:24:59
【问题描述】:

鉴于下面的一段代码,其中 blueViewController 是 iVar。
问题:为什么不直接实例化 iVar?

BlueViewController *blueController = [[BlueViewController alloc]initWithNibName:@"BlueView" bundle:nil];
self.blueViewController = blueController;
[blueController release];

【问题讨论】:

    标签: objective-c memory-management


    【解决方案1】:

    这取决于你在课堂上的位置。如果您在 init(和 dealloc)方法中,建议直接引用 ivar 以避免 setter 逻辑中的任何副作用。因此在初始化时我会这样做

    _blueViewController = [[BlueViewController alloc] initWithNibName:@"BlueView" bundle:nil];
    

    但是在其他任何地方我都会按照你的做法去做。然后,如果 getter/setter 中有任何自定义逻辑,我知道它会运行。

    为了阐述@Vladimar 的观点,retain 的综合设置器将执行一些类似于此的内存管理:

    - (void)setMyObject:(MyObject *)newMyObject
    {
      // If it's the same object we don't need to do anything
      if (_myObject != newMyObject) {
        [newMyObject retain];
        [_myObject release];
        _myObject = newMyObject;
      }
    }
    

    在设置 ivars 时让 getter/setter 担心所有这些逻辑会更安全。

    【讨论】:

      【解决方案2】:

      您可以直接初始化 iVar,但您拥有的代码还可以处理先前 blueViewController 值的内存管理。直接访问 iVar,您必须在分配新值之前手动释放先前的值。

      【讨论】:

        【解决方案3】:

        如果您愿意,您可以在一条线上完成所有操作。重要的是平衡 +alloc 与 -release 或 -autorelease。所以,你可以说:

        self.blueViewController = [[[BlueViewController alloc] initWithNibName:@"BlueView" bundle:nil] autorelease];
        

        这很好,但有些人更喜欢避免 -autorelease,而有些人只是更喜欢更简单的步骤和/或更短的代码行。在这方面使用您所做的中间变量会有所帮助,而且不会花费任何成本。

        【讨论】:

          【解决方案4】:

          这取决于属性是否为retain。大多数对象属性被保留;这是一个保留属性的样子:

          - (void)setBlueViewController:(BlueViewController *)bvc {
              if (bvc != blueViewController) {    // blueViewController is local ivar
                  [blueViewController release];
                  blueViewController = [bvc retain];
              }
          }
          

          因此,您在那里所做的是创建 +2 的保留计数。当您init 时,这是+1;该物业然后retains ,将其提升至+2。你的dealloc 释放一次,这使它降到+1……你已经泄露了该属性。因为您是alloc/init-ing 变量,所以您不想使用setter;相反,将其直接分配给实例变量。

          通过直接实例化它,它为您省去了其他release 的麻烦——更少的代码行意味着更少的错误。例如,您可能无意中输入了retain,直到您的程序崩溃时才意识到它,因为您保留了一个庞大的类...

          当然,正如 Caleb 所说,您可以自动释放,但这实际上是让对象在内存中闲置,直到运行循环完成。它更容易,并且给你更多的控制,只是不用担心。将alloc/init 分配给 ivar 没有任何问题;事实上,这是最好的方法。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-07-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多