В первом примере:
[c add : [[Complex alloc] withReal: 1.0 andImag: 2.0]];
Вы выделили объект с номером ссылки 1, и он не освобожден, поэтому это утечка памяти, поскольку вы не сохраняете указатель на этот объект, поэтому вы не можете отправить выпуск на него.
Вы можете изменить его для автоматического освобождения временного объекта:
[c add : [[[Complex alloc] withReal: 1.0 andImag: 2.0] autorelease]];
Вероятно, вы используете init в имени, чтобы указать на тот факт, что объект не является автоматически выпущенным, и пользователь должен управлять управлением памятью:
initWithReal:(double)r andImag:(double)i
Второй пример верен.
Какао предоставляет множество методов (как статических, так и членских), которые возвращают объекты с автоматически освобождением, например, [NSString stringWithString:@"example"]
, так что вы можете создавать методы, возвращающие объекты с автоматически освобождением, чтобы вам не приходилось иметь дело с освобождением:
Complex * c = [Complex complexWithReal:1.0 andImag:2.0]
Вы также можете создать метод, который принимает необработанные данные, например, что-то вроде addReal:(double)r andImag:(double)i
, так что вы можете пропустить шаг alloc / init.
Другим вариантом является использование структур, используемых в Какао (CGRect
и т. Д.). Они такие же, как в C, что означает, что они размещены в стеке, и они исчезают, как только выходят из области видимости, в отличие от выделенных объектов в куче с помощью alloc / init. Подходит для «маленьких» предметов, которые часто используются, но часто вы не хотите держать их рядом.
Что касается GC, я не вижу никаких причин, по которым GC не сможет справиться с освобождением объекта - хотя я не использовал его много (хотя смотрел только на пару примеров - я предпочитаю управлять памятью самостоятельно - если не использую python
...)