автоматический подсчет ссылок (ARC) и retainCount - PullRequest
2 голосов
/ 02 марта 2012

Я в процессе преобразования моего проекта в ARC, и столкнулся с особой проблемой.У меня есть класс, который управляет кэшем файлов, которые загружаются из сети.Каждый файл хранится в файловой системе iPhone, и связанный с ним объект сохраняется в моем классе менеджера для него.Другие объекты, которые хотят использовать файл, запрашивают у моего менеджера объект кэша и сохраняют его до тех пор, пока им нужен файл.

Но время от времени менеджер очищает кэш, удаляя старыйфайлы.Конечно, он не должен удалять файлы, которые используются в данный момент.До ARC я обнаружил, что с помощью retainCount связанного объекта:

// if retainCount is 1 then only the cache has a reference to it
if( obj.retainCount <= 1 ) {
    [obj deleteFile];
    [cache removeObject:obj];
}

Это сработало отлично [и да, я знаю о предупреждениях о ненадежности retainCount, но по своему опыту, если retainCount> 1вы точно знаете, что его сохранили более одного объекта]

Однако с ARC вы больше не можете использовать retainCount.Я мог бы ввести свой собственный механизм подсчета хранения и потребовать, чтобы все объекты, использующие файлы, явно сохраняли и освобождали файловые объекты.Но это ошибка, и именно эту задачу ARC должен решить.

Знаете ли вы лучший способ добиться того же?

Ответы [ 3 ]

5 голосов
/ 02 марта 2012

Эта функция лучше всего обрабатывается NSCache и NSDiscardableContent.При этом используются явные вызовы start и end, что позволяет вам сохранять четкие ссылки на вещи, которые вам не обязательно хранить (потому что вы создадите их автоматически).Использование NSCache для этого также дает вам другие преимущества, такие как автоматический сброс отбрасываемого содержимого, даже когда вы приостановлены.Без чего-то вроде NSCache вы были бы убиты, когда памяти стало меньше, вместо того, чтобы позволить вам сбросить лишний кеш.

Тем не менее, вы создали другую систему.Эта конкретная проблема - то, для чего нужны ссылки weak.Ваш кеш должен поддерживать слабую ссылку на объекты, а не сильную ссылку.Есть несколько подходов, которые обсуждаются в Массив без сохранения для делегатов .Я лично предпочитаю решение NSValue.Утвержденный ответ звучит здорово и просто, но вам нужно хорошо понимать ARC и CFArray, чтобы правильно его использовать.Решение NSValue гораздо менее сложно.

В идеале, если ваши файловые объекты знают, что они кэшированы, они могут указать кешу удалить их во время их dealloc.В противном случае вы можете периодически удалять пустые значения из массива.

0 голосов
/ 13 ноября 2012

Не уверен, что это применимо к вашим потребностям, но знаете ли вы Ассоциативные ссылки ? Они позволяют вам присоединять подчиненные объекты к главному объекту, так что подчиненный объект живет столько же, сколько мастер. Это позволяет не только прикреплять объекты к объекту, над которым у вас нет контроля, но вы также можете узнать об их окончании.

Интересно, можете ли вы использовать это для отслеживания вашего "obj", прикрепив к нему объект пользовательского класса, и этот вызываемый класс 'dealloc будет вызван, если "obj" будет освобожден? После этого вы можете выполнить удаление файла.

0 голосов
/ 02 марта 2012

Просто установите некоторую переменную int в реализации вашего объекта, увеличивайте ее каждый раз, когда объект сохраняется, и переопределяйте его метод dealloc, чтобы уменьшить его. Тот же самый счетчик, но он хорош только для пользовательских объектов.

...