На первый взгляд кажется, что ваш пример будет работать, но на самом деле он создает утечку памяти.
По соглашению в какао и какао-прикосновении любой объект, созданный с использованием [[SomeClass alloc] initX]
или [SomeClass newX]
, создается с сохранением количества единиц. Вы отвечаете за вызов [someClassInstance release]
, когда вы закончили свой новый экземпляр, как правило, в вашем методе dealloc
.
Если это сложно, это когда вы присваиваете свой новый объект свойству вместо переменной экземпляра. Большинство свойств определяются как retain
или copy
, что означает, что они либо увеличивают количество удержаний объекта при его установке, либо делают копию объекта, оставляя исходный нетронутый.
В вашем примере, вы, вероятно, это в вашем файле .h
:
@property (retain) EditingViewController *editingViewController;
Таким образом, в первом примере:
EditingViewController *controller =
[[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil];
// (1) new object created with retain count of 1
self.editingViewController = controller;
// (2) equivalent to [self setEditingViewController: controller];
// increments retain count to 2
[controller release];
// (3) decrements retain count to 1
Но для второго примера:
// (2) property setter increments retain count to 2
self.editingViewController =
// (1) new object created with retain count of 1
[[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil];
// oops! retain count is now 2
Вызвав метод autorelease
на свой новый объект, прежде чем передавать его на setter, вы попросите пул авторесурсов взять собственность на объект и выпустить его некоторое время в будущем, поэтому на некоторое время у объекта есть два владельца, чтобы соответствовать его счету удержания, и все очень сложно.
// (3) property setter increments retain count to 2
self.editingViewController =
// (1) new object created with retain count of 1
[[[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil]
// (2) give ownership to autorelease pool
autorelease];
// okay, retain count is 2 with 2 owners (self and autorelease pool)
Другим вариантом будет присвоение нового объекта непосредственно переменной экземпляра вместо средства настройки свойств. Предполагая, что ваш код имени Базовому переменный экземпляра editingViewController
:
// (2) assignment to an instance variable doesn't change retain count
editingViewController =
// (1) new object created with retain count of 1
[[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil];
// yay! retain count is 1
Это тонкая, но существенная разница в коде. В этих примерах self.editingViewController = x
является синтаксическим сахаром для [self setEditingViewController: x]
, но editingViewController
является простой старой переменной экземпляра без кода сохранения или копирования, сгенерированного компилятором.
Смотрите также Why does this create a memory leak (iPhone)?
@property (сохранить) РедактированиеViewController * editViewController; // (2) приращения уставки свойств сохраняются до 2 self.editingViewController = // (1) новый объект, созданный с сохранением count 1 [[EditingViewController alloc] initWithNibName: @ «EditingView» bundle: nil]; // Упс! сохранить счет сейчас 2 Это неправда. Метод setter, созданный компилятором, освободит объект, переданный как параметр, и сохранит свойство. Таким образом, счет сохранения будет равен 1, и проблем нет. –