Позвольте мне попытаться объяснить это по-другому.
Метод, имеющий в своем имени alloc, copy или new, выделяет память для объекта и передает право собственности на этот объект вызывающей стороне, и вызывающая сторона несет ответственность за освобождение этой памяти.
В вашем методе viewDidLoad вы вызываете метод, который дает вам право собственности на объект. Ваш метод обязан выпустить его. Однако, прежде чем сделать это, вы хотите что-то с этим сделать - в конце концов, именно поэтому вы распределили это не просто для того, чтобы выпустить его, но чтобы сделать что-то полезное с ним.
Независимо от того, что вы хотите с ним делать, вы должны разблокировать его (или автоматически выпустить *). В этом случае вы используете объект для передачи его в self.breadTypes. self.breadTypes может не выглядеть как метод, но это так (это сеттер). Вы передаете это breadArray. Он делает то, что нужно с ним. Он может сохранить его для последующего использования или скопировать из него некоторую информацию или сделать копию всего этого. Ваш viewDidLoad на самом деле не волнует. Предполагается, что self.breadTypes делает то, что ему нужно, и когда он возвращается, ему все равно, что вы делаете с breadArray.
И что вы делаете с этим, это то, что вы должны делать со всем, что у вас есть - отпустить (или автоматически выпустить * это).
Вот почему вы должны использовать переменную temp, breadArray. Вы не можете полностью освободить результаты от alloc в той же строке, так как объект будет освобожден раньше, чем self.breadTypes может иметь в нем:
self.breadTypes = [[[NSArray alloc] initWithObjects:@"White", ..., nil] release];
Таким образом, вы вынуждены присвоить временную переменную, передать ее в self.breadTypes, а затем освободить объект, сохраненный в breadArray.
Теперь вы можете попытаться сделать это таким образом, чтобы не использовать временную переменную:
- (void)viewDidLoad {
self.breadTypes = [[NSArray alloc] initWithObjects:@"White", @..., nil];
[self.breadTypes release];
}
но это не очень эффективно, так как вы вызываете еще один метод (self.breadTypes как метод получения), который вам действительно не нужен, если вы только что сохранили значение во временной переменной.
* Теперь, как сказал респондент, вы можете использовать авто-релиз для альтернативной версии:
- (void)viewDidLoad {
self.breadTypes = [[[NSArray alloc] initWithObjects:@"White", ..., nil]
autorelease];
}
Apple призывает нас дважды подумать о том, хотим ли мы использовать авто-релиз против релиза. Авто-релиз не может быть лучшим выбором для любой ситуации. Мне лично нравится убирать за собой как можно скорее, и я не использую авто-релиз без необходимости. Автоматически освобожденные объекты освобождаются в конце выполнения цикла выполнения, например, вскоре после возвращения viewDidLoad. Вы должны прочитать немного больше об авто-выпуске (и об управлении памятью на iPhone, который немного отличается от MacOS X Cocoa), поскольку я упрощаю все это.
Кстати: если вы retain
объект, вы принимаете на себя владение им, и вы будете нести ту же ответственность снова, release
после того, как вы закончите с ним.