Создание и создание объектов в target-c - PullRequest
1 голос
/ 06 июля 2011

Учитывая фрагмент кода ниже, где blueViewController - это iVar.
Вопрос: Почему бы не создать экземпляр iVar напрямую?

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

Ответы [ 4 ]

2 голосов
/ 06 июля 2011

Это зависит от того, где вы находитесь в вашем классе.Если вы используете метод init (и dealloc), рекомендуется обратиться к ivar напрямую, чтобы избежать каких-либо побочных эффектов в логике сеттера.Поэтому в init я бы сделал

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

Но где-нибудь еще я бы сделал это так, как вы это сделали.Затем, если в геттере / сеттере есть какая-либо нестандартная логика, я знаю, что она будет запущена.

Для разработки на точке @ Vladimar синтезированный сеттер для сохранения будет выполнять некоторое управление памятью, аналогичное следующему:

- (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;
  }
}

Гораздо безопаснее позволить геттерам / сеттерам беспокоиться обо всей этой логике каждый раз, когда вы устанавливаете свои ивары.

2 голосов
/ 06 июля 2011

Вы можете инициализировать iVar напрямую, но имеющийся у вас код также управляет памятью для предыдущего значения blueViewController. При непосредственном доступе к iVar вам придется сбросить предыдущее значение вручную перед назначением нового.

1 голос
/ 06 июля 2011

Зависит от того, является ли свойство retain или нет. Большинство свойств объекта сохраняются; Вот как выглядит свойство retain:

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

Итак, что вы делаете там, создаете счет удержания +2. Когда вы init, это +1; свойство тогда retain s, увеличивая это до +2. Ваш dealloc выпускает его один раз, что снижает его до +1 ... и вы слили это свойство. Поскольку вы alloc / init определяете переменную, вы не хотите использовать установщик; вместо этого присвойте его непосредственно переменной экземпляра.

Создавая его напрямую, он избавляет вас от проблем, связанных с другими release - чем меньше строк кода, тем меньше ошибок. Например, вы могли бы случайно набрать retain и не понимать, пока ваша программа не выйдет из строя, потому что вы сохранили массивный класс ...

Конечно, как сказал Калеб, вы могли бы автоматически выпустить, но это фактически позволяет объекту лежать в памяти, пока цикл выполнения не закончится. Это гораздо проще, и дает вам больше контроля, просто не беспокоиться об этом. Нет ничего плохого в назначении alloc / init для ивара; на самом деле, это лучший способ сделать это.

1 голос
/ 06 июля 2011

Вы можете сделать все это в одной строке, если хотите.Важно сбалансировать + alloc с -release или -autorelease.Итак, вы можете сказать:

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

Это хорошо, но некоторые люди предпочитают избегать -autorelease, а некоторые просто предпочитают более простые шаги и / или более короткие строки кода.Использование промежуточной переменной, как вы сделали, помогает в этом отношении, и это ничего не стоит.

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