Основная проблема, связанная с памятью, о которой вам еще нужно знать, это сохранение циклов. Это происходит, когда один объект имеет сильный указатель на другой, но целевой объект имеет сильный указатель на оригинал. Даже если все другие ссылки на эти объекты будут удалены, они все равно будут держаться друг за друга и не будут освобождены. Это также может происходить косвенно, когда цепочка объектов может иметь последний в цепочке, ссылающийся на более ранний объект.
По этой причине существуют квалификаторы владения __unsafe_unretained
и __weak
. Первый не будет сохранять какой-либо объект, на который он указывает, но оставляет открытой возможность того, что этот объект исчезнет, и он указывает на плохую память, тогда как последний не сохраняет объект и автоматически устанавливает ноль, когда его цель освобождается. Из этих двух, __weak
обычно предпочтительнее на платформах, которые его поддерживают.
Вы бы использовали эти квалификаторы для таких вещей, как делегаты, когда вы не хотите, чтобы объект сохранял свой делегат и потенциально приводил к циклу.
Еще одна важная проблема, связанная с памятью, связана с обработкой объектов Core Foundation и памяти, выделенной с использованием malloc()
для таких типов, как char*
. ARC не управляет этими типами, только объектами Objective-C, поэтому вам все равно придется разбираться с ними самостоятельно. Базовые типы Foundation могут быть особенно хитрыми, потому что иногда их необходимо соединить с соответствующими объектами Objective-C и наоборот. Это означает, что управление должно быть передано и обратно от ARC при соединении между типами CF и Objective-C. Некоторые ключевые слова, связанные с этим мостовым соединением, были добавлены, и у Майка Эша есть отличное описание различных случаев мостового соединения в его длительной статье ARC .
В дополнение к этому, есть несколько других, менее частых, но все еще потенциально проблематичных случаев, которые подробно описаны в опубликованной спецификации .
Большая часть нового поведения, основанного на хранении объектов до тех пор, пока на них есть сильный указатель, очень похожа на сборку мусора на Mac. Тем не менее, технические основы очень разные. Вместо того, чтобы иметь процесс сборщика мусора, который запускается через регулярные промежутки времени для очистки объектов, на которые больше не указывают, этот стиль управления памятью опирается на жесткие правила сохранения / освобождения, которым мы все должны следовать в Objective-C.
ARC просто берет повторяющиеся задачи по управлению памятью, которые нам приходилось выполнять годами, и выгружает их в компилятор, поэтому нам больше не нужно о них беспокоиться. Таким образом, у вас не будет проблем с остановкой или профилей памяти пилообразной памяти, возникающих на платформах для сбора мусора. Я испытал оба этих фактора в своих приложениях Mac для сбора мусора, и мне не терпится узнать, как они ведут себя в ARC.
Подробнее о сборке мусора по сравнению с ARC см. этот очень интересный ответ Криса Латтнера в списке рассылки Objective-C , где он перечисляет многие преимущества ARC по сравнению с сборкой мусора Objective-C 2.0. Я столкнулся с несколькими проблемами GC, которые он описывает.