Вопрос

Обновление : я редактировал код, но проблема сохраняется ...

Привет всем,
это мой первый пост здесь - я нашел это место отличным ресурсом для решения многих моих вопросов. Обычно я изо всех сил стараюсь что-то исправить самостоятельно, но на этот раз я действительно не знаю, что происходит не так, поэтому я надеюсь, что кто-то может мне помочь.
Я создаю приложение для iPhone, которое анализирует пару XML-файлов с помощью TouchXML. У меня есть класс XMLParser, который заботится о загрузке и разборе результатов. Я получаю утечки памяти, когда я анализирую XML-файл более одного раза с одним и тем же экземпляром XMLParser. Вот один из фрагментов анализа (только соответствующая часть):

for(int counter = 0; counter < [item childCount]; counter++) {  
        CXMLNode *child = [item childAtIndex:counter];
        if([[child name] isEqualToString:@"PRODUCT"]) 
        {
            NSMutableDictionary *product = [[NSMutableDictionary alloc] init];
            for(int j = 0; j < [child childCount]; j++) {
                CXMLNode *grandchild = [child childAtIndex:j];
                if([[grandchild stringValue] length] > 1) {
                    NSString *trimmedString = [[grandchild stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
                    [product setObject:trimmedString forKey:[grandchild name]];
                }
            }

            // Add product to current category array
            switch (categoryId) {
                case 0:
                    [self.mobil addObject: product];
                    break;
                case 1:
                    [self.allgemein addObject: product];
                    break;
                case 2:
                    [self.besitzeIch addObject: product];
                    break;
                case 3:
                    [self.willIch addObject: product];
                    break;
                default:
                    break;
            }
            [product release];
        }

    }  

В первый раз, когда я анализирую xml, в приборах нет утечек, в следующий раз я получаю много утечек (NSCFString / NSCFDictionary).
Инструменты указывают мне на эту часть внутри CXMLNode.m , когда я копаюсь в просочившемся объекте:

theStringValue = [NSString stringWithUTF8String:(const char *)theXMLString];
if ( _node->type != CXMLTextKind )
   xmlFree(theXMLString);
}

return(theStringValue);  

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

Любая помощь высоко ценится, спасибо!

Это было полезно?

Решение

Скорее всего, проблема в этой строке:

[self.mobil addObject:[product copy]];

Вызывая копию product , вы создаете новый экземпляр NSMutableDictionary с счетчиком сохранения 1. Однако экземпляр mobil будет увеличивать сохранение копии считается, когда вы отправляете ему сообщение addObject: , поэтому количество сохраненных копий теперь равно 2. Вообще говоря, объект отвечает за обработку собственной памяти объекта, поэтому каждый раз, когда вы отправляете сообщение setFoo: или addObject: , вы можете просто передать объект напрямую, даже если он автоматически освобожден или вы планируете выпустить его сразу после вызова; ответственность за сохранение передаваемого объекта лежит на получателе, если он должен удерживать его.

Поскольку вы не присваивали копию какой-либо переменной, у вас нет указателя, который можно использовать для уменьшения счетчика хранения копии сейчас, когда она вам больше не интересна, поэтому даже если mobil выпускает копию продукта в какой-то момент, она никогда не достигнет счетчика сохранения 0. Ваш оператор [выпуск продукта] в конце цикла for освобождает исходный product объект, а не копия, которую вы создали.

Вместо этого попробуйте следующее и посмотрите, подходит ли инструмент лучше:

[self.mobil addObject:product];

Другие советы

Проще говоря, каждый раз, когда вы используете copy , вы также должны где-то использовать release / autorelease .

И в этом случае, еще более простой ответ - не использовать copy , поскольку вы ничего не делаете с оригинальной версией product после Вы скопировали это.

Я сам решил проблему. Это было довольно глупо, но, возможно, кто-то может столкнуться с тем же, поэтому я собираюсь опубликовать это здесь.

1) У меня был изменяемый массив, настроенный как переменные экземпляра, например:

@interface XMLParser : NSObject {

// ...  
NSMutableArray *mobil;  
// ...  
}   
@property(nonatomic, retain) NSMutableArray *mobil;  
@end  

Каждый раз, когда я хотел восстановить новые данные внутри, я делал:
    self.mobil = ноль;
Что не то, что я хотел сделать, так что это лучший подход:
    [self.mobil removeAllObjects];

2) Метод dealloc должен быть таким, чтобы исправить утечки (потому что mobil определяется как свойство):
    - (недействительно) dealloc {
      [мобил релиз];
      self.mobil = ноль;
  }

Уфф, это было много работы, чтобы выяснить - надеюсь, это спасет кого-то еще некоторое время :-)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top