Как исправить утечку памяти iOS из _NSCFNumber?

Это мой код, в котором я перезагружаю определенные разделы _collectionView. Когда я проверяю утечки памяти с помощью шаблона Leaks в инструментах Xcode 6.3, он показывает утечку в строке

[_collectionView reloadSections:indexToLoad];

и _NSCFNumber как просочившийся объект. Вот мой код:

NSMutableIndexSet* indexToLoad = [NSMutableIndexSet new];
for (NSInteger index in array) {
    if (index != NSNotFound) {
        [indexToLoad addIndex:index];
    }
}
if (indexToLoad.count > 0) {
    [_collectionView reloadSections:indexToLoad];
}

Как я где-то читал, "инструмент утечек показывает, где была выделена утечка, но не показывает строку кода, вызвавшую утечку", как я могу найти причину утечки? И как устранить эту утечку?

ПРИМЕЧАНИЕ. ARC включен для класса, в котором выполняется этот код (весь проект включен ARC). Также этот код работает в основном потоке.

Спасибо за ответы заранее :)


person Dattatraya Anarase    schedule 09.07.2015    source источник
comment
Там нет линии, где происходит утечка. Утечка происходит, когда все ссылки на этот объект выходят за рамки, но никто не удосужился собрать объект. В вашем случае ваш код даже не компилируется с самого начала, поэтому можете ли вы показать нам фактический код, с которым у вас возникли проблемы?   -  person JustSid    schedule 09.07.2015
comment
Действительно, покажите нам код, который на самом деле работает. Если этот код компилируется, вам действительно нужно включить некоторые предупреждения компилятора.   -  person gnasher729    schedule 10.07.2015


Ответы (1)


Я заметил, что вы перебираете массив и переводите его содержимое в NSInteger. Поскольку вы не можете добавить NSInteger к массиву Objective-C, я предполагаю, что это массив NSNumber, который просто является классом, в котором происходит утечка.

Когда вы добавляете объект (например, NSNumber) в коллекцию (например, NSArray, NSSet и т. д.), коллекция создает ссылку STRONG на этот объект. Это означает, что когда этот NSNumber выйдет из области действия, ARC или сборщик мусора не придут и не выпустят его. Однако это может вызвать некоторые проблемы, одна из которых заключается в сохранении циклов.

То, что я подозреваю, происходит (я не могу быть уверенным без фактического тестирования вашего полного кода), так это то, что когда NSMutableIndexSet выходит за рамки, появляется ARC и пытается освободить все NSNumber объекты, которые он содержит, но находит, что не может, так как они все еще сохраняются в массиве. Если нет, то где-то в коде вы цепляетесь за один или несколько экземпляров NSNumber, и ARC это не нравится.

Решение. ARC не является панацеей, когда речь идет об управлении памятью. Это делает управление памятью намного более удобным, и из-за этого люди склонны полагать, что они могут написать любой код, который им нравится, а ARC позаботится обо всем остальном. Вам все еще нужно знать о своих ссылках (strong против weak) и когда использовать каждую из них. Также убедитесь, что вы знаете, что такое состояние по умолчанию; например @property NSNumber *num; эквивалентно @property (nonatomic, strong) NSNumber *num;

person Rob Sanders    schedule 09.07.2015