распределение и инициализация объекта в задаче c

<p>в чем разница между следующими двумя способами выделения и инициации объекта?</p><pre><code>acontroller *tempacontroller = [[acontroller alloc] init]; self.acontroller = tempacontroller; [tempacontroller release]; </code></pre><p>а также</p><pre><code>self.acontroller= [[acontroller alloc] init]; </code></pre><p>большая часть примера apple использует первый метод. зачем вам выделять, инициализировать и возражать, а затем немедленно освобождать?</p>

<p>как отметили другие, два фрагмента кода, которые вы показываете, не эквивалентны (по причинам управления памятью). что касается того, почему первое выбрано над вторым:</p><p>правильная формулировка последнего будет</p><pre><code>self.acontroller= [[[acontroller alloc] init] autorelease]; </code></pre><p>по сравнению с предыдущим это добавляет дополнительные издержки за счет использования пула автоматического выпуска, и в некоторых случаях приводит к ненужному расширению срока службы объекта (до тех пор, пока не будет освобожден пул автоматического выпуска), что увеличит объем используемой памяти вашего приложения.</p><p>другая "возможная" реализация (в зависимости от того, откуда взят пример) просто:</p><pre><code>acontroller = [[acontroller alloc] init]; </code></pre><p>однако установка переменной экземпляра напрямую не рекомендуется в любом другом месте, кроме как в методах init или dealloc. в другом месте вы всегда должны использовать методы доступа.</p><p>это подводит нас к реализации, показанной в примере кода:</p><pre><code>acontroller *tempacontroller = [[acontroller alloc] init]; self.acontroller = tempacontroller; [tempacontroller release]; </code></pre><p>это следует передовой практике, поскольку:</p><ul> <li>избегает авто-релиза;</li> <li>это делает семантику управления памятью сразу понятной;</li> <li>он использует метод доступа для установки переменной экземпляра.</li> </ul>

<p>если вы используете xcode, он может помочь вам обнаружить такой код с помощью статического анализатора. просто нажмите build >> построить и проанализировать</p><p><img src="https://i.stack.imgur.com/13knx.png" alt="alt text"></p><p>это покажет вам очень полезное сообщение в таких частях кода.</p><p><img src="https://i.stack.imgur.com/3oysb.png" alt="alt text"></p>

<p>также обратите внимание, что вы хотите сократить код до одной строки, поэтому многие люди используют autorelease:</p><pre><code>self.acontroller = [[[acontroller alloc] init] autorelease]; </code></pre><p>хотя в теории авто-релиз iphone как-то дороже (никогда не слышал четкого объяснения, почему), и поэтому вы можете явно освободить сразу после назначения объекта в другом месте.</p>

<p>еще одна вещь, на которую следует обратить внимание, это то, что ваш пример зависит также от определения @property acontroller.</p><p>если он был определен как <code>@property (readwrite, retain) id acontroller;</code>, тогда ваш пример работает, в то время как если он определен как <code>@property (readwrite, assign) id acontroller;</code>, то дополнительный вызов release вызовет освобождение вашего объекта.</p>

<p>вы могли бы также сделать</p><pre><code>@property (nonatomic, retain)acontroller *acontroller; ... self.acontroller= [[acontroller alloc] init]; [acontroller release]; </code></pre><p>с сохраняющим свойством, и он будет функционировать таким же образом, но лучше использовать другой способ (для сохранения свойств), потому что он менее запутан, этот код заставляет его выглядеть так, как будто вы назначаете acontroller, а затем он удаляется из памяти, когда на самом деле это не потому, что setacontroller сохраняет его.</p>