Это очень хороший вопрос, я ждал несколько часов в надежде, что кто-то даст достаточный ответ, но, поскольку никто даже не ответил, я попробую.Сначала я прокомментирую ваш подход, затем попытаюсь предложить, как мне это обойти.
Это определенно очень плохая идея для освобождения - таким образом освободить объект от его делегата.Подумайте только о том, как объекты (например, CLLocationManager) вызывают своих делегатов - они просто вызывают их в середине какого-то метода.Когда вызов делегата завершен, выполнение кода возвращается к методу объекта, который уже был освобожден.БАМ!
Давайте на минутку забудем о том, что это плохая идея.Я вижу два варианта, как исправить так легко.Во-первых, autorelease
вместо release
дает объекту немного больше времени для спама - он, по крайней мере, выживет, возвращаясь от делегата.Этого должно быть достаточно для большинства случаев, по крайней мере, если автор API хорошо выполнил свою работу и инкапсулировал логику за основным классом API (в случае CLLocationManager может ожидаться отключение GPS ...).Второй вариант - отложить выпуск (на ум приходит performSelector:withObject:afterDelay:
), но это скорее обходной путь для плохо реализованных API.
Так что, если выпускать это не очень хорошая идея, тогда что?
Ну, что вы на самом деле получаете, выпустив CLLocationManager?Освобождение этих нескольких байтов памяти не спасет ваше приложение от завершения, когда в системе недостаточно памяти.В любом случае, действительно ли вам нужен текущий адрес только один раз?
Я предлагаю вам инкапсулировать задачи, связанные с CLLocationManager, в отдельный класс, возможно, даже в одиночный - этот класс станет его делегатом, и он будетпозаботьтесь о том, чтобы связаться с CLLocationManager и проинформировать ваше приложение о результатах (возможно, отправив NSNotification
).CLLocationManager будет освобожден из dealloc
этого класса, и никогда в результате обратного вызова делегата.stopUpdatingLocation
должно хватить, освобождая несколько байтов памяти - ну, вы можете сделать это, когда ваше приложение переходит в фоновый режим, но пока ваше приложение работает, освобождение этих нескольких байтов не приводит к значительному улучшению потребления памяти.
** Добавление **
Для делегата естественно и правильно иметь право собственности на объект, для которого он выступает в качестве делегата.Но делегат не должен освобождать объект в результате обратного вызова.Однако есть одно исключение, и это обратный вызов, сообщающий, что обработка завершена.В качестве примера для этого можно привести NSURLConnection
connectionDidFinishLoading:
, в котором говорится в документации «Делегат больше не будет получать сообщений».У вас может быть класс, загружающий группу файлов, каждый из которых имеет свой NSURLConnection
(с вашим классом в качестве делегата), выделяя и освобождая их по мере загрузки файлов. Поведение
CLLocationManager
отличается.В вашей программе должен быть только один экземпляр CLLocationManager.Этим экземпляром управляет некоторый код, возможно, одноэлементный, который может быть выпущен, когда приложение переходит в фоновый режим, и повторно инициализируется при его пробуждении.Продолжительность жизни CLLocationManager
будет такой же, как у его управляющего класса, который также действует как делегат.