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