Сохранение / освобождение возвращаемых объектов
Я новичок в Objective-C, так это может быть глупый вопрос.
Я не могу не видеть сходства между ObjC и COM Microsoft в отношении управления памятью (AddRef
/Release
vs retain
/release
). В среде COM это более или менее навязывается вам всегда AddRef
(retain
) объект перед возвращением его вызывающему объекту. Из того, что я видел до сих пор (я третий через Программирование Cocoa® для Mac® OS X (3-е издание)), память часть Управления несколько нечеткая.
предполагая, что нет GC, каков идиоматический способ вернуть объект?
5 ответов
читать Руководство По Программированию Управления Памятью о autorelease бассейны.
в Objective-C, по соглашению, объекты должны быть возвращены автоматически (если метод, возвращающий объект, не имеет имени, начинающегося с "alloc", "new", "copy" или "mutableCopy"). Autoreleased объекты отслеживаются Objective-C в пуле и автоматически обрабатываются, что означает, что вам не нужно заботиться о отправке им окончательного выпуска. Это значительно упрощает подсчет ссылок по сравнению с COM, и именно поэтому вы не видите ни release
вызовы возвращаемых объектов большую часть времени. Напротив, то же соглашение указывает, что все объекты, возвращаемые методом, имя которого начинается с alloc, new, copy или mutableCopy, являются ответственностью вызывающего метода. Вы должны вручную вызвать release на этих объектах или ваша программа будет иметь утечки памяти.
какао идет вокруг ограничений AddRef
/Release
в COM путем введения третьего брата;autorelease
.
-
retain
- мне это нужно, пусть это останется. -
release
- мне это больше не нужно, вы можете удалить его немедленно. -
autorelease
- мне это не нужно, но пусть это останется на несколько секунд, если кто-то еще захочет забрать его первым.
это крошечное дополнение позволяет большинству возвращаемых значений быть ручками , а если у нас был сбор мусора. Если вы не заинтересованы в сохранении возвращаемого значения, просто не делайте ничего лишнего.
чтобы заставить это работать, существует соглашение (соглашение достаточно хорошее, чтобы компилятор автоматически выполнял работу с памятью для вас с предстоящей дугой):
- имена методов, начинающиеся с этих должны вернуться сохранил экземпляры:
alloc
copy
new
retain
- все остальные должны возвращает autoreleased экземпляров.
три примера реализации для того, как это может быть применено на практике:
-(NSString*)newHelloWorldString {
NSString* s = [NSString stringWithString:@"Hello world"];
// Apply retain because s in now autoreleased
return [s retain];
}
-(NSString*)helloWorldString {
NSString* s = [[NSString alloc] initWithString:@"Hello world"];
// Apply autorelease because s is now retained.
return [s autorelease];
}
-(NSString*)fullName {
// No memory management needed, everything is autoreleased and good.
NSString* fn = [self firstName];
NSString* ln = [self lastName];
NSString* s = [NSString stringWithFormat:@"%@ %@", fn, ln];
return s;
}
вообще-то что-то вроде
вернуться [объект autorelease];
и вы можете сохранить на другом конце.
Если вы планируете развернуть на Lion / iOS5 или используете последний SDK, также проверьте ARC.
по существу, я бы рекомендовал сделать класс, который получает его, сохранить его. Я. E класс stackoverflow получает ответ объекта.
Я.е
-(void) setAnswer:(Answer*) _answer{
self.answer = _answer; // If the answer is created from a returned message.
[_answer release];
}
edit: я думаю, что я, возможно, поставил неправильный материал там сейчас, когда я смотрю на него во второй раз . Означало что-то вроде:
Answer *_answer = [stackoverflow createAnswer];
self.answer = _answer;
[_answer release];
Если вы возвращаете объект, это до владельца, чтобы сохранить его, я бы избежать autoreleases, где это возможно, потому что как только nspool срабатывает, эти объекты исчезли, и если они все еще используются, это вызовет проблемы.
i.e Answer * answer = [stackoverflow getAnswer] и если ответ был создан в методе getanswer, то тот, кто извлекает его, несет ответственность за его освобождение.
смысл?