«инициализация» свойства, которое сохраняется - PullRequest
1 голос
/ 21 декабря 2009

В мире iPhone Objective-C я видел этот паттерн повсюду и все время использую его сам, не понимая, что происходит:

In Test.h

@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 есть сохранение, когда оно объявлено в свойстве, зачем нам нужно создавать новый объект инициализации NSMutableArray, назначать его testArray и выпускать? Почему я не могу просто начать использовать testArray в viewDidLoad, ничего не делая?

Я знаю, что есть некоторые споры о том, как лучше всего это сделать (создать новый объект или использовать объект автоматического выпуска), но в обоих случаях мы получаем testArray с счетом сохранения 1. Как я полагаю, сохранить свойство уже дает. Так зачем создавать этот объект init?

Ответы [ 2 ]

7 голосов
/ 21 декабря 2009

Свойство 'retain' не создает автоматически NSMutableArray для вас. Скорее, это просто означает, что всякий раз, когда вы делаете присваиваете что-то этому свойству, оно сохраняется.

Если бы ваш код был таким:

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

Тогда self.testArray будет nil, и, таким образом, по сути это будет no-op. Пока вы не назначите что-то для 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"];
}
1 голос
/ 21 декабря 2009

«retain» в директиве @property указывает, что установщик должен сохранять входное значение вместо простого копирования значения. Это не имеет ничего общего с выделением (выделением памяти) и инициализацией (конструированием объекта) объекта. retain в директиве @property просто увеличивает счетчик сохранения при вызове метода установки (что позволяет вам делать что-то вроде self.myobject = что-то без специального вызова retain.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...