Могу ли я использовать [самосохранение] для удержания самого объекта в target-c? - PullRequest
0 голосов
/ 23 марта 2011

Я использую [self retain], чтобы держать объект сам, и [self release], чтобы освободить его в другом месте. Это очень удобно иногда. Но на самом деле это референсный цикл, или тупик, который решает большинство систем сбора мусора. Интересно, может ли пул авто-релизов target-c найти петли и преподнести мне сюрпризы, выпустив объект до достижения [self release]. Мой путь поощряется или нет? Как я могу гарантировать, что сборка мусора, если она там будет, не будет слишком умной?

Ответы [ 2 ]

3 голосов
/ 23 марта 2011

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

Теоретически, объект должен жить так долго, как это полезно.Полезные объекты можно легко обнаружить: на них непосредственно ссылаются где-то в стеке потоков, или, если вы сделали график всех ваших объектов, доступным по некоторому пути, связанному с объектом, на который ссылаются где-то в стеке потоков.Объекты, которые живут «сами по себе» без ссылки, не могут быть полезны, поскольку ни один поток не может добраться до них, чтобы заставить их что-то выполнить.

Вот как работает сборщик мусора: он пересекает ваш граф объектов и собираеткаждый объект без ссылки.Имейте в виду, Objective-C не всегда собирает мусор, поэтому необходимо было установить некоторые правила.Это рекомендации по управлению памятью для какао .

Короче говоря, оно основано на понятии «владение».Когда вы смотрите на счетчик ссылок на объект, вы сразу же знаете, сколько других объектов зависит от него.Если объект имеет счетчик ссылок 3, это означает, что три других объекта нуждаются в нем для правильной работы (и, таким образом, владеют им).Каждый раз, когда вы сохраняете ссылку на объект (за исключением редких случаев), вы должны вызывать его метод retain.И прежде чем отбросить ссылку, вы должны вызвать ее метод release.

Существует несколько других правил, касающихся создания объектов.Когда вы вызываете alloc, copy или mutableCopy, объект, который вы получаете, уже имеет повторный счет 1. В этом случае это означает, что вызывающий код отвечает за освобождение объекта, когда он не требуется.Это может быть проблематично, когда вы возвращаете ссылки на объекты: теоретически, когда вы его возвращаете, он вам больше не нужен, но если вы вызовете release, он сразу же будет уничтожен!Это - то, где NSAutoreleasePool объекты входят. Вызывая autorelease для объекта, вы отказываетесь от владения владением им (как если бы вы вызывали release), за исключением того, что ссылка не была немедленно отозвана:вместо этого он передается в NSAutoreleasePool, который освобождает его после получения самого сообщения release.(Всякий раз, когда часть вашего кода вызывается обратно платформой Какао, вы можете быть уверены, что пул авто-выпуска уже существует.)

Это также означает, что вы не владеете объектами, если вы не вызывали alloc,copy или mutableCopy на них;другими словами, если вы получите ссылку на такой объект, вам не нужно вызывать release для него.Если вам нужно держать вокруг такого объекта, как обычно, вызовите retain на нем, а затем release, когда вы закончите.

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

1 голос
/ 23 марта 2011

Если вы используете модель сохранения / освобождения памяти, это не должно быть проблемой. Ничто не пойдет на поиски вашего [self retain] и не испортит его. Однако это может быть не так, если вы когда-нибудь переключитесь на сборку мусора, где -retain и -release - no-ops.

Вот еще одна тема на SO по той же теме.

Я бы повторил ответ, который включает фразу «всепоглощающее чувство слабости». Это не противозаконно, но кажется плохим планом, если на то нет достаточно веской причины. Если ничего другого, это кажется подлым, и это никогда не бывает хорошо в коде. Обратите внимание на предупреждение в этой теме, чтобы использовать -autorelease вместо -release.

...