У меня утечка памяти в этом методе Objective-C, кто-нибудь может сказать мне где? - PullRequest
1 голос
/ 01 марта 2012

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

-(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];
}

Спасибо

Ответы [ 5 ]

3 голосов
/ 01 марта 2012

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

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

Должно быть:

NSMutableArray *retVal = [arrayToHoldSorted mutableCopy];
2 голосов
/ 01 марта 2012

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

Эта строка:

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

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

NSArray* arrayToHoldSorted = [inputArray sortedArrayUsingComparator...

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

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

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

2 голосов
/ 01 марта 2012

Заменить:

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

С:

NSMutableArray *retVal = [arrayToHoldSorted mutableCopy];

Вы пропускаете первое значение retVal.

1 голос
/ 01 марта 2012

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

return [retVal autorelease];

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

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

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

1 голос
/ 01 марта 2012

Вы выделяете 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) .....
...