2012-03-01 5 views
1

Я получаю exc_bad_access где-то в коде ниже. Я не понимаю, где это, если бы кто-нибудь мог пролить свет на него? Это метод, который использует NSMutableArray словарей и сортирует их по одному из элементов в словаре. Утечка памяти почти наверняка в бите с блоком, но я думаю, что я что-то фундаментальное в поиске его не хватает ...У меня есть утечка памяти в этом объектно-c-методе, может ли кто-нибудь сказать мне, где?

-(NSMutableArray*)sortBicyclesByDistanceToDevice:(NSMutableArray*)inputArray{ 

    NSArray *arrayToHoldSorted = [[[NSArray alloc] init]; 

    arrayToHoldSorted = [inputArray sortedArrayUsingComparator:^(id a, id b){ 

     NSNumber *first = [[a objectForKey:kDistanceFromDevice] objectForKey:kValue]; 
     NSNumber *second = [[b objectForKey:kDistanceFromDevice] objectForKey:kValue]; 
     return [first compare:second];}]; 


    NSMutableArray *retVal = [[NSMutableArray alloc] init]; 

    retVal = [arrayToHoldSorted mutableCopy]; 

    [arrayToHoldSorted release]; 

    return [retVal autorelease]; 
} 

Благодаря

ответ

1

Вы выделяете arrayToHoldSorted (1) - который вы никогда не используете, как вы тогда получите NSArray назад от sortedArrayUsingComparator (2). И затем вы отпускаете его потом (3), когда вы его не владеете. Вы делаете тот же трюк для retVal, выделяя NSMutableArray, а затем перезаписываете свою ссылку на него, получая новый NSMutableArray из [arrayToHoldSorted mutableCopy];

NSArray *arrayToHoldSorted = [[NSArray alloc] init]; .. // 1 

arrayToHoldSorted = [inputArray sortedArrayUsingComparator:^(id a, id b) ..... // 2 

[arrayToHoldSorted release]; // 3 

Просто назначьте возвращение NSArray из sortedArrayUsingComparator в ссылку ...

NSArray* arrayToHoldSorted = [inputArray sortedArrayUsingComparator:^(id a, id b) ..... 
+0

спасибо за вход –

+0

Это было мое удовольствие! – Damo

2

Replace:

NSMutableArray *retVal = [[NSMutableArray alloc] init]; 
retVal = [arrayToHoldSorted mutableCopy]; 

С:

NSMutableArray *retVal = [arrayToHoldSorted mutableCopy]; 

Утечка первого значения retVal.

3

Похоже, вы назначаете retVal на номер NSMutableArray, а затем переназначайте сразу после. Исправлено исходное значение NSMutableArray. То есть:

NSMutableArray *retVal = [[NSMutableArray alloc] init]; 
retVal = [arrayToHoldSorted mutableCopy]; 

Должно быть:

NSMutableArray *retVal = [arrayToHoldSorted mutableCopy]; 
+0

Спасибо за ответ –

1

Я думаю, что проблема в том, что в этой строке:

возвращение [RetVal autorelease];

Вы выпускаете то, что вы не сохранили. Также в этой строке:

NSArray * arrayToHoldSorted = [[[NSArray alloc] init];

у вас есть дополнительный [, который не помогает. Но самое главное, вы можете использовать статический анализатор в XCode для диагностики такого рода ошибок, вместо того, чтобы приставать к добрым людям в StackOverflow.

+0

Я никогда не слышал о статическом анализаторе, я посмотрю, спасибо –

+0

Когда вы нажимаете Command-B для создания своего проекта, попробуйте вместо Shift-Command-B проанализировать. Он также доступен в меню продукта и даже с помощью кнопки «Запуск», если он долгое время щелкнет по нему. Анализатор - ваш друг. Я пытаюсь заставить себя проанализировать каждый 4-й или 5-й сборник, чтобы сохранить свои навыки управления памятью [sucky] в порядке – Damo

+0

. Это определенно стоит держать один код без ошибок анализатора, даже если это означает переписывание раздела кода, где анализатор просто не получается. Делайте, как предлагает Дамо. Не делай того, что я сделал. Я оставил его до конца очень большого проекта, и мне потребовались годы, чтобы все почистить. Конечно, стоит того. –

2

Там более одного!

Эта линия:

NSArray *arrayToHoldSorted = [[[NSArray alloc] init]; 

Является ли утечка памяти, так как вы сразу переназначить указатель. Его следует удалить. Просто объявить массив на следующей строке:

NSArray* arrayToHoldSorted = [inputArray sortedArrayUsingComparator... 

Этот метод возвращает autoreleased объект, так что вам не нужно, чтобы выпустить его позже.

Аналогичный шаблон с изменяемым массивом.Вы выделяете/init, затем перезаписываете новый объект, давая еще одну утечку. Опять же, удалите строку alloc/init и просто объявите в следующей строке. mutableCopy дает вам неявно сохраненный объект, поэтому вам нужно его автообновить.

У вас, похоже, создается впечатление, что alloc/init необходимо каждый раз, когда вы объявляете переменную объекта. Это не тот случай.

+1

На самом деле я был под этим впечатлением. Я думаю, что мое управление mem должно работать –

+0

ARC очень приятно! – jrturton

 Смежные вопросы

  • Нет связанных вопросов^_^