Сохранение / освобождение возвращаемых объектов

Я новичок в 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, то тот, кто извлекает его, несет ответственность за его освобождение.

смысл?