Что эквивалентно '[[что-то сохраняют] авто-релиз]' в ARC? - PullRequest
6 голосов
/ 10 марта 2012

Что эквивалентно [[something retain] autorelease] в ARC?

У меня проблема, когда класс DBRequest вызывает моего делегата для обозначения завершения.Затем мой делегат устанавливает для экземпляра DBRequest значение nil, что и делает это.Но затем, когда стек выпадает из моего делегата и возвращается к DBRequest, он, конечно, затем падает.

Если бы я не был в ARC, в моем делегате я просто сделал бы [[theDbRequest retain] autorelease] перед выпускоммоя ссылка на него, так что он выживет достаточно долго, пока следующий цикл цикла не выпустит его автоматически.

Что мне делать в ARC?

Ответы [ 3 ]

6 голосов
/ 10 марта 2012

Как насчет добавления чего-то вроде

__strong DBRequest * myself = self;
[delegate reportDone];

Я думаю, что это увеличит собственный объект до конца функции, предотвращая его преждевременную смерть.

3 голосов
/ 10 марта 2012

Как говорит @matt, если вы просто ничего не делаете, ARC должен очистить, когда ваш объект освобожден - присваивая DBRequest, который вы создаете, переменной обработчика экземпляра, которая ( при условии , конечно, ваш объект переживает объект вы создаете).

Если вам нужно освободить DBRequest до того, как ваш объект умрет, вам нужен ARC-совместимый "трюк", эквивалентный [[theDbRequest retain] autorelease]. Теперь, если вы не создаете свои собственные пулы автоматических выпусков, ваш предыдущий подход сработает в конце текущего события. Следуя этой логике, попробуйте:

  1. Добавьте метод к вашему классу, который просто устанавливает theDbRequest в nil, давайте назовем это cleanUpTheDbRequest.
  2. Измените ваш обратный вызов делегата, чтобы вызывать [self performSelectorOnMainThread:@selector(cleanUpTheDbRequest) withObject:nil waitUntilDone:NO] вместо прямого присвоения nil theDbRequest

Это должно задержать присвоение nil до окончания текущего события, как это сделал ваш трюк с авто-выпуском. Это также работает, если ваш DBRequest живет в нескольких событиях - предыдущий метод запускается в конце события, в которое вызывается autorelease, этот метод в конце события, в котором вызывается метод делегата.

3 голосов
/ 10 марта 2012

Затем мой делегат устанавливает для экземпляра DBRequest значение nil, что делает его равным. Но затем, когда стек выпадает из моего делегата и возвращается к DBRequest, он, конечно, вылетает.

Конечно, это всегда была плохая стратегия, и ваш [[theDbRequest retain] autorelease] всегда просто прикрывал проблему, да?

Просто ничего не делай. Таким образом, ваша переменная экземпляра остается неизменной; И что? Вы знаете, что ARC выпустит его для вас, когда вас освободят.

Важно не выпустить theDbRequest, а установить для ссылки DBRequest значение you (делегат) равным nil, чтобы он не пытался перезвонить вам, когда вас больше не существует. Ваш собственный сделка будет хорошим местом для этого.

Надеюсь, я правильно понял проблему. Если нет, напишите какой-нибудь код!

...