Основная проблема, связанная с памятью, о которой вам еще нужно знать, это сохранение циклов. Это происходит, когда один объект имеет сильный указатель на другой, но целевой объект имеет сильный указатель на оригинал. Даже если все другие ссылки на эти объекты будут удалены, они все равно будут держаться друг за друга и не будут освобождены. Это также может происходить косвенно, когда цепочка объектов может иметь последний в цепочке, ссылающийся на более ранний объект.
Именно по этой причине существуют __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, которые он описывает.