На общий вопрос не очень хороший ответ, кроме , как он работает .Objective-C без сборщика мусора - это язык с явным управлением памятью.Это означает, что вы должны заботиться о семантике владения объектом.Есть соглашения, которые помогут вам сделать это, но в конечном итоге вы должны обратить внимание на то, кто чем владеет.
Теперь вы можете утверждать, что простое присутствие в стеке вызовов является своего рода de facto * 1006.* владение, и, конечно, можно разработать язык таким образом.Тем не менее, на практике это повлечет за собой много лишнего хранения и освобождения, которое не нужно во всем хорошо спроектированном коде и обеспечит надежный буфер безопасности только в очень немногих крайних случаях.Это, вероятно, также затруднило бы поиск множества подлинных ошибок управления памятью.
Вы, конечно, вправе не согласиться с этим анализом, но ни вы, ни я ничего не можем сказать по этому поводу.
В конкретном случае, который вы описываете, мне кажется, проблема в том, что вы не правильно определили семантику владения при передаче BOTTOM из MIDDLE.Есть две возможности:
- MIDDLE возвращает слабую ссылку, которая впоследствии может исчезнуть.В этом случае до TOP 101 *, прежде чем делать что-либо, что может изменить состояние BOTTOM - и вызов
release
на MIDDLE, безусловно, попадает в эту категорию. - MIDDLE присваивает вызывающему временное владениес эталоном, который, как ожидается, будет оставаться хорошим до тех пор, пока пул авто-выпуска не истощится:
return [[BOTTOM retain] autorelease];
В этом случае безопасно release
СРЕДНИЙ впоследствии.
Оба из этих подходов являются действительными в качестве Objective-Cстоит, и оба будут работать.Вам просто нужно четко определить, что вы используете, и действовать соответственно.Ваша ошибка возникла в результате выполнения первого, но ожидалось, что она будет вести себя как вторая.