Цель C - утечка при установке массива в качестве объекта словаря - PullRequest
0 голосов
/ 13 января 2012

Я написал класс, который действует как фильтр. Я прохожу три объекта:

  1. NSArray, который содержит объекты для фильтрации (эти объекты имеют свойство timestamp)
  2. NSMutableArray (который будет содержать имена разделов для табличного представления, периоды, основанные на временных метках). Мне нужен этот массив, потому что я должен отсортировать периоды.
  3. NSMutableDictionary, в котором ключами будут имена разделов, значения - NSMutableArrays, в которых хранятся элементы за заданный период.

В классе, из которого я передаю эти объекты, есть tableView, в котором я отображаю элементы. Этот класс имеет свои собственные NSMutableArray и NSMutableDictionary, я не инициализирую их, только сохраняю соответствующие возвращаемые значения класса фильтра. В методе delloc я освобождаю их. В классе фильтра есть метод:

+ (void)insertItem:(id)item forPeriod:(NSString *)period toContainer:(NSMutableDictionary *)container {

    if ( ![[container allKeys] containsObject:period] ) {

        // the period isn't stored, create and store it
        NSMutableArray *periodArray = [[NSMutableArray alloc] init];
        [container setObject:periodArray forKey:period];
        [periodArray release];
        periodArray = nil;
   }

   // store the item
   NSMutableArray *arrayForPeriod = [container objectForKey:period];
   [arrayForPeriod addObject:item];
   arrayForPeriod = nil;
}

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

Ответы [ 2 ]

0 голосов
/ 13 февраля 2014

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

Когда в вашем словаре есть несколько сотен объектов, вы тратите очень много времени и памяти. Словарь не имеет массива всех ключей, спрятанных где-то, он должен создавать его каждый раз, когда вы вызываете ваш метод. Это копирует несколько сотен указателей (дешево) и сохраняет их (дорого). containsObject для массива сравнивает объект с каждым объектом в массиве, вызывая isEqual: это дорого. Это сравнение NSString каждый раз. Массив автоматически освобождается, и когда он, наконец, исчезает, все ключи в нем освобождаются. Опять дорого.

NSDictionary использует хеш-таблицу, поэтому [objectForKey] немедленно перейдет к нужному объекту. Одна операция вместо, возможно, сотен.

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

Да, это считается утечкой, потому что ваша переменная является локальной переменной.Тогда у вас все еще есть объект в памяти, но нет ссылки на него.Помните, что init делает сохранение + сохранение сделанное в словаре = 2 сохраняет.Просто создайте свой массив, используя

NSMutableArray * periodArray = [[[NSMutableArray alloc] init] autorelease]

Это ясно?

...