2010-01-06 1 views
24

Предположим, я создаю новый класс для iPhone в Objective-C. В одном из моих методов init я хочу вручную выделить некоторую память. Таким образом, я мог бы что-то вроде этого:Как я должен обрабатывать сбой в методе init: в Objective-C?

- (id)initWithSomeObject:(SomeObject *)someObject { 
    self = [super init]; 
    if (self != nil) { 
    myObject = someObject; 
    [myObject retain]; 
    if ((memory = calloc(1, sizeof(SomeStruct)) == NULL) { 
     // What should I do here to clean up 
     [self release]; 
     self = nil; 
    } 
    } 
    return self; 
} 

Теперь, если предположить, что calloc() может потерпеть неудачу, и что не в состоянии выделить память катастрофична для моего объекта, что я должен делать внутри, если орган, чтобы очистить правильно? Есть ли идиома Objective-C или шаблон, который я должен использовать?

Редактировать: Я включил код, отправленный Роба Напиром. Но мне еще нужно выпустить myObject, верно? Или добавленный код каким-то образом вызывает dealloc()?

+2

Не беспокойтесь о том, запускает ли он dealloc(). Да, но дело не в этом. Дело в том, что [self release] уравновешивает предыдущий вызов + alloc, поэтому все ваши необходимые релизы были выполнены, и система теперь позаботится об освобождении в соответствующее время. В большинстве случаев «подходящее время» возможно, как только вызывается [self release], но это может быть позже, если есть какие-либо отложенные автореализаторы. Но приведенный выше код верен, и больше ничего не требуется. –

+0

В качестве примечания: я понимаю, что calloc/malloc никогда не вернет NULL, система просто убьет ваше приложение, когда у вас закончится или будет недостаточно памяти. Я предполагаю, что Apple подумал, что это было проще сделать, а затем сбой приложения с непроверенных указателей NULL/nil. –

ответ

26

Да, вы должны освободить себя, а затем вернуть nil.

[self release]; 
self = nil; 

См в Концепции в Objective-C Руководство по программированию Issues with Initializers.

3

Вам необходимо очистить все, что вам нужно, а затем установить собственную ссылку на nil. Apple, Dev Portal есть статья:

Link

+0

geez - по крайней мере оставьте комментарий, когда вы downvote! – psychotik

+0

Не забудьте освободить себя, или вы просочитесь. (Понятия не имею, кто это сделал, вы правы). –

1

Я просто пытался. -dealloc вызывается из-за [self release], поэтому myObject не нужно будет выпускать в initWithSomeObject. Конечно, вы можете переместить myObject = [someObject retain]; (я предпочитаю этот стиль в случае, если -retain может по какой-то причине сбой) под вызовом, который может выйти из строя (если это возможно).