iPhone: вернуть NSMutableArray в методе, все еще выпуская
Я пытаюсь понять немного больше об управлении памятью. Зная, что мне нужно выпустить что-нибудь, что я инициализировал или выделил, я запутался в следующем:
- (NSMutableArray *)getData {
NSMutableArray *data = [[NSMutableArray alloc] init];
NSString *first = @"First object";
[data addObject:first];
NSString *second = @"Second object";
[data addObject:second];
return data;
}
Поскольку я использовал alloc и init, я знаю, что должен освободить свой объект данных. Но если я добавляю autorelease в часть init или в return, то происходит сбой при запуске метода.
Как правильно сделать что-то подобное с правильным управлением памятью для iPhone?
3 ответа
Вы должны автоматически выпустить, как вы сказали. Вызывающая сторона, вероятно, должна сохранить, как это - особенно если сохранить в переменной экземпляра:
NSMutableArray *array = [[obj getData] retain];
Позже, когда это будет полностью сделано с этим:
[array release]; // balances the retain above
Вы на правильном пути. Вы должны соединить каждый alloc
/init
либо с release
или же autorelease
, что приведет к очистке объекта, как только окончательная ссылка на него исчезнет.
Шаблон выглядит примерно так:
- (SomeObject*)generateSomeObject
{
SomeObject* someObject = [[[SomeObject alloc] init] autorelease];
...
return someObject;
}
Вы присваиваете результат этого метода переменной экземпляра? Помните, что вещи, добавленные в пул автоматического выпуска, будут выпущены в какой-то момент в будущем (обычно в конце цикла выполнения), поэтому, если вы назначите его переменной экземпляра, и конец цикла выполнения наступит, Ваша переменная экземпляра в конечном итоге будет указывать на мусор (или иногда на другой объект), если вы не сохраните его.
Наименование метода (getData
) предполагает, что возвращаемый объект должен быть автоматически освобожден, поэтому вы можете создать массив с [NSMutableArray array]
заполните как обычно, а затем верните из метода.
Если код, который вызывает getData
хочет, чтобы массив пережил итерацию цикла выполнения, он должен retain
это, но также, это должно быть обязательно release
массив, когда он, наконец, закончил с этим - это обычно делается в вашем dealloc
метод.