代码之家  ›  专栏  ›  技术社区  ›  Z S

“正在初始化”保留的属性

  •  1
  • Z S  · 技术社区  · 16 年前

    在iPhone objective-c的世界里,我到处都能看到这种模式,我自己也一直在使用它,但我并不真正了解发生了什么:

    @interface Test: UIViewController
    {
       NSMutableArray *testArray;
    }
    @property (retain, nonatomic) NSMutableArray *testArray;
    

    在测试中

    @implementation Test
    @synthesize testArray
    
    - (void) viewDidLoad
    {
    
      // why do we do this?
      NSMutableArray *init = [[NSMutableArray alloc] init]; 
      self.testArray = init;
      [init release];
    
      [self.testArray addObject: @"A"]; // why can't I do this directly?
      ...
    }
    
    - (void) dealloc
    {
      [testArray release];
      [super dealloc];
    }
    

    我的问题是:如果testArray在属性中声明时有一个retain,为什么我们需要创建一个新的NSMutableArray init对象,将其分配给testArray并释放?为什么我不能在viewDidLoad中开始使用testArray而不做任何其他事情?

    我知道在这方面的最佳方法(创建新对象或使用自动释放对象)上存在一些争论,但在这两种情况下,我们最终得到了保留计数为1的testArray。我相信“retain”属性已经给出了它。那么为什么需要创建这个init对象呢?

    2 回复  |  直到 16 年前
        1
  •  7
  •   BJ Homer    16 年前

    “retain”属性不会自动为您创建NSMutableArray。相反,它只是表明,无论何时 如果将某些内容分配给该属性,它将被保留。

    如果您的代码为:

    - (void) viewDidLoad
    {
      [self.testArray addObject: @"A"];
    }
    

    nil ,因此它本质上是不可操作的。除非您将某些内容分配给self.testArray,否则它是空的。

    事情是这样的。

    - (void) viewDidLoad
    {
      // we need to assign an NSMutableArray to self.testArray.
    
      NSMutableArray *init = [[NSMutableArray alloc] init];
      // The array has been retained once (by the call to |alloc|)
    
      self.testArray = init;
      // The array is assigned to a property with the 'retain' attribute
      // Thus, the array has now been retained twice
    
      [init release];
      // We release the array, so it now is retained once.
    
      // We now have an array in self.testArray, so we can add something to it.
      [self.testArray addObject: @"A"];
    }
    
        2
  •  1
  •   ennuikiller    16 年前

    @property指令中的“retain”指定setter应该保留输入值,而不是简单地复制值。它与分配(留出内存)和初始化(构造对象)对象无关。@property指令上的retain仅在调用setter时增加retain计数(这允许您执行self.myobject=something之类的操作,而无需专门调用retain)。