почему освобождает возврат (односторонний возврат), а автоматический возврат (идентификатор)? - PullRequest
1 голос
/ 06 декабря 2011

Если я сделаю это -

SomeObject* someObject = [[SomeObject alloc] init];
[[someObject release] release];

Я предполагаю, что моя программа не будет аварийно завершать работу, потому что второй избыточный релиз действует ни на что.

Принимая во внимание

[[someObject autorelease] autorelease];

может произойти сбой, потому что объект освобождается дважды при передаче по цепочке.

Это только вопрос любопытства, я думаю, у меня до сих пор с этим не было проблем.

Ответы [ 3 ]

7 голосов
/ 06 декабря 2011

(См. этот ответ для объяснения того, что делает oneway.)

Ваш первый пример даже не компилируется, так как void! = nil. Но если вы просто вызовете release два раза для объекта с счетом сохранения 1, он наверняка потерпит крах.

Что касается того, почему release возвращает void, а autorelease возвращает id: Первый говорит: Мне больше не нужен этот объект, вы можете от него избавиться. Таким образом, если он что-то вернет и вы оперируете, вы, скорее всего, оперируете мертвым объектом В отличие от этого autorelease более или менее говорит «Скоро мне больше не понадобится объект, но пусть он останется, пока я не закончу с текущим методом».

Итак, как вы видите, они похожи в том, что они говорят Мне больше не понадобится этот объект , но они различаются во времени: release говорит "Вы можете избавиться объекта сейчас", в то время как autorelease говорит " вы можете избавиться от объекта позже".

4 голосов
/ 06 декабря 2011

Полагаю, это в основном сделано для простоты использования, как, конечно, можно обойтись без (и поставить каждый autorelease в отдельной строке):

Всякий раз, когда вы release объект, вы 'сделано с этим (или, по крайней мере, вы должны быть).Нет необходимости возвращать объект, так как он, возможно, уже был уничтожен, и в любом случае вызывающая сторона не должна работать с объектом, если он еще не уничтожен (т.е. кто-то еще имеет ссылку на него).

С другой стороны, autorelease часто используется вместе с init / alloc и просто отмечает объект для последующего уничтожения.Всякий раз, когда вы используете autorelease, вы можете быть почти уверены, что объект будет использован впоследствии.Независимо от того, возвращаете ли вы его напрямую или работаете с ним самостоятельно (например, после [[[SomeClass alloc] init] autorelease]), очень удобно возвращать объект, поскольку он сохраняет явную строку кода для autorelease.Также полезно иметь autorelease непосредственно в той же строке: на return [someObject autorelease] вы можете непосредственно видеть, что это объект с автоматическим выпуском.Если вы используете его с init / alloc, вы можете сразу увидеть, что этот объект не нуждается в другом release.

1 голос
/ 06 декабря 2011

Полагаю, вы сами ответили на свой вопрос. Вызов autorelease может быть в самом начале жизни объекта, поэтому, возможно, вам потребуется сохранить несколько строк кода с помощью следующего оператора:

[anotherObject callMethodWithArg: [myObject autorelease]];

Действительно, это полезно. Однако вы вызываете релиз в самом конце кода, который использует ваш объект. Говоря о немедленном освобождении, вы говорите, что вам больше не нужен этот объект. Так что нет смысла повторно использовать его экземпляр. Другой вариант заключается в том, что вызов release может на самом деле немедленно освободить объект, поэтому возвращение неверного указателя не будет хорошей идеей =)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...