Утечка NSDecimalNumberPlaceHolder

У меня есть приложение для iPad, которое я тестирую в Инструментах перед бета-тестированием. Я избавился от всех утечек памяти, кроме одной, и не могу найти по ней никакой информации. Я сбит с толку, что делать, поскольку мой код никогда не упоминает утечку объекта, который является экземпляром NSDecimalNumberPlaceHolder.

Наверняка я использую NSDecimalNumber. Я создаю 2 десятичных знака для каждой операции пользователя, и каждый раз, когда я запускаю цикл приложения (которое выполняет некоторую математическую операцию над двумя NSDecimalNumbers), я генерирую четыре экземпляра этой вещи NSDecimalPlaceHolder. Поскольку я не знаю, как он создается, я не знаю, как освободить или освободить его, чтобы не генерировать эти 16 утечек снова и снова.

Возможно ли, что на самом деле это не утечки?

Я запустил анализатор XCode, и он не сообщает о проблемах.

Я делаю следующее:

Я отправляю десятичное число с моего контроллера на мою модель (analyzer_), которая выполняет операции и отправляет результат.

[[self analyzer_] setOperand:[NSDecimalNumber decimalNumberWithString:anotherStringValue]];

Метод setOperand выглядит так:

-(void)setOperand:(NSDecimalNumber*)theOperand
{
NSLog(@"setOperand called");
operand_ = theOperand;
//[operand_ retain];    

}

Обратите внимание, что если я не сохраняю операнд_ «где-то», я получаю сбой BAD_ACCESS. В настоящее время я сохраняю и выпускаю его позже, когда операнд и ранее предоставленный операнд (queuedOperand_) обрабатываются. Например:

{
[self performQueuedOperation];
queuedOperation_ = operation;
queuedOperand_ = operand_;
}   

return operand_;
[operand_ release];

где PerformQueuedOperation:

-(void)performQueuedOperation
{
   [operand_ retain];
   if ([@"+" isEqualToString:queuedOperation_]) 
   {
    @try
    {
    operand_ = [queuedOperand_ decimalNumberByAdding:operand_];
    }
    @catch (NSException *NSDecimalNumberOverFlowException)
    {
    //viewController will send decimal point error message
    }
   <etc for the other operations>
}

Дайте мне знать, если это не ясно. Спасибо.


person ndpmcintosh    schedule 03.10.2011    source источник
comment
NSDecimalNumberPlaceHolder, вероятно, является конкретным классом, который выделяется при использовании NSDecimalNumber. Попробуйте опубликовать код для просмотра. Кроме того, что происходит, когда вы запускаете анализатор своего кода?   -  person ThomasW    schedule 03.10.2011
comment
Спасибо за быстрый ответ @ThomasW. Я отредактировал вопрос, чтобы предоставить запрошенную информацию.   -  person ndpmcintosh    schedule 03.10.2011
comment
Я думаю, вам придется очистить свой код, хорошо понимая, как должно работать сохранение/освобождение. Метод setOperand:, вероятно, должен сохранять новое значение операнда_ и освобождать старое значение. Если вам не нужно делать ничего особенного в установщике, вам следует подумать об изменении operand_ на @property с сохранением. Другие варианты использования операторов удержания и выпуска следует убрать. 'возвратный операнд_; [выпуск_операнда];' код не освобождает операнд_, потому что возврат приведет к выходу из метода. (Компилятор должен выдать предупреждение об этом.)   -  person ThomasW    schedule 03.10.2011
comment
Спасибо за советы. Никаких предупреждений. Я пробовал оба способа (с @property и без него, а также с сохранением и освобождением в установщике и без него). Я уберу их после возвращения. Попытка выпустить и сохранить его в методе setOperand в конечном итоге дает мне 2 невыпущенных экземпляра NSDecimalNumber из моего приложения (я не знаю, почему). Заполнители создаются Foundation. У меня есть несколько идей. Я отчитаюсь, когда попробую их.   -  person ndpmcintosh    schedule 03.10.2011
comment
Обязательно освободите operand_ в вашем методе Dealloc.   -  person ThomasW    schedule 03.10.2011
comment
Также не забудьте удалить ненужные сохранения, такие как в PerformQueuedOperation.   -  person ThomasW    schedule 03.10.2011
comment
Я освобождаю его в Dealloc и избавляюсь от сохранения в queuedOperation. Однако у меня есть еще одно сохранение в методе, который вызывает executeQueuedOperation (performOperation), и я не могу избавиться от него, иначе я быстро вылетаю, пытаясь отправить сообщение в queuedOperand_, которое было освобождено. Оказывается, проблема не в NSDecimalPlaceHolder. Это мой NSDecimalNumbers.   -  person ndpmcintosh    schedule 05.10.2011


Ответы (1)


Попробуйте Heapshot в инструментах, см.: Когда утечка не является утечкой?

Если все еще есть указатель на память, которая больше не используется, это не утечка, а потерянная память. Я часто использую Heapshot, он действительно отлично работает. Также включите запись подсчета ссылок в инструменте «Распределения» и выполните детализацию. Вот скриншот: введите здесь описание изображения

person zaph    schedule 03.10.2011
comment
Спасибо за вашу помощь. Я не эксперт по инструментам, но я не понимаю, как Heapshot помогает изолировать проблему. Однако по подсчету ссылок я вижу, что я всегда отказываюсь от нескольких экземпляров моего NSDecinal со счетом 1 и что это, похоже, вызвано моим методом PerformOperation (который вызывает PerformQueuedOperation). Однако я не могу избавиться от еще одного [operand_retain], потому что, если я это сделаю, приложение выйдет из строя, потому что оно в конечном итоге попытается получить доступ к экземпляру queuedOperand_, который был освобожден. У меня может быть дефект во всей конструкции моего контроллера модели. - person ndpmcintosh; 05.10.2011
comment
Ваша проблема не уникальна, я часто ее вижу. Да, это проблема дизайна, и, вероятно, простого решения нет. Итак, вас волнует утечка? Достаточно ли памяти утекло за время жизни вашего приложения, чтобы что-то изменить? Учтите всю жизнь, включая то, что она находится на заднем плане. Если ваше приложение может жить с утечкой, пусть так и будет, прагматизм часто побеждает совершенство. - person zaph; 05.10.2011
comment
Объем съедаемой памяти небольшой. Но поскольку я хотел бы, чтобы это приложение было принято Apple, я обеспокоен по этой причине. - person ndpmcintosh; 05.10.2011
comment
Apple не откажется от утечек памяти, я сомневаюсь, что их это вообще волнует, пока они не вызывают сбоев. Есть много других способов утечки памяти, которые хуже, чем утечки, такие как сохранение циклов и сохранение неиспользуемой памяти. В коде, над которым я работал, есть даже комментарий: «Лучше слить этот сбой». - person zaph; 05.10.2011
comment
На самом деле я немного улучшил его и уменьшил утечку (немного). Я также подсчитал, что при нормальном использовании, даже после многих тысяч операций, утечка не должна вызывать значительных проблем с памятью. Вперед. Спасибо за ваш вклад. - person ndpmcintosh; 08.10.2011
comment
Уважение может быть таким же простым, как голосование за ответы и комментарии тех, кто помог, не только здесь, но и в других вопросах, которые вы задали, и во многих ответах, которые вы прочитали и извлекли пользу, это простой щелчок. Вы получаете 2 очка репутации за каждый принятый ответ и в 15 можете начать голосовать за ответ и тем самым благодарить. Я часто голосую за ответы. - person zaph; 08.10.2011
comment
Не могу. Недостаточно очков репутации прямо сейчас. Я проверю позже, когда сделаю. - person ndpmcintosh; 08.10.2011
comment
Принятие и голосование отдельно, вы приняли свой первый вопрос. Я только что проголосовал за один из ваших вопросов, чтобы помочь вам преодолеть первоначальный скачок репутации. - person zaph; 09.10.2011