Проблема утечки памяти - PullRequest
3 голосов
/ 15 марта 2011

Может, кто-нибудь посоветует, почему в этом коде произошла утечка памяти?

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

- (void)viewDidDisappear:(BOOL)animated {

// Empty array to be sure it is empty
[playerArray removeAllObjects];

//============CLEAN OUT DOUBLE NAMES FROM ARRAY==============//
NSArray *sortedDummyArray = [[NSArray alloc] initWithArray:selectedPlayersArray];
    ////>>>>The line above is line 84<<<<<<<////

// Sort the array
sortedDummyArray = [sortedDummyArray sortedArrayUsingSelector:@selector(compare:)];

NSMutableArray *finalArray = [[NSMutableArray alloc]initWithArray:sortedDummyArray];
    ////>>>>>> Possible memory leak on line 84 <<<<<<<<//// 



int xx = [sortedDummyArray count];
int yy;
int counter = 0;
int rr = 0;

for (int oo = 0; oo < xx; oo++) {
    yy = [finalArray count];

    for (int zz = 0; zz < yy; zz++) {

        // If hit, clean out the double name
        if ([[sortedDummyArray objectAtIndex:oo] isEqualToString:[finalArray objectAtIndex:rr]]) {

            counter++;

            // Check if there is more than one of this name
            if (counter > 1) {
                [finalArray removeObjectAtIndex:rr];
                rr--;
                counter--;
            }
        }
        rr++;
    }
    counter = 0;
    rr = 0;
}

[sortedDummyArray retain];

// Save who is in the game

AccessQuestionsDB *shufflePlayersFunction = [AccessQuestionsDB new];
finalArray = [shufflePlayersFunction shufflePlayers: finalArray];
[shufflePlayersFunction release];

TempPlayersInTheGame *savePlayersInTheGame = [TempPlayersInTheGame new];
[savePlayersInTheGame saveSelectedPlayers:finalArray];
[savePlayersInTheGame release];

[finalArray release]; //>>>> see comment below
    ////>>>>>Incorrect decrement of the reference count of an object that is not owned at this point by the caller <<<<<<///// 

    [sortedDummyArray release];
[super viewDidDisappear:animated];

}

Ответы [ 3 ]

3 голосов
/ 15 марта 2011

Ваша первая утечка вызвана тем, что вы звоните:

[sortedDummyArray retain];

Вы уже вызвали alloc, который делает это, но в конце концов, вы только что освободили его (так что удалить вышеуказанную строку) Затем вы также переназначаете ее, что неверно.

Ваша вторая утечка вызвана тем, что вы установили finalArray с alloc, а затем заменили его результатамифункции.Вы можете исправить это, заменив эту строку:

NSMutableArray *finalArray = [[NSMutableArray alloc]initWithArray:sortedDummyArray];

На эту:

NSMutableArray *finalArray = [NSMutableArray arrayWithArray:sortedDummyArray];

А затем удалив эту строку:

[finalArray release];

Итак, в целом ваша функция будет выглядеть так:

- (void)viewDidDisappear:(BOOL)animated {

    // Empty array to be sure it is empty
    [playerArray removeAllObjects];

    //============CLEAN OUT DOUBLE NAMES FROM ARRAY==============//   
    // Sort the array
    NSArray *sortedDummyArray = [selectedPlayersArray sortedArrayUsingSelector:@selector(compare:)];

    NSMutableArray *finalArray = [NSMutableArray arrayWithArray:sortedDummyArray];    

    int xx = [sortedDummyArray count];
    int yy;
    int counter = 0;
    int rr = 0;

    for (int oo = 0; oo < xx; oo++) {
        yy = [finalArray count];

        for (int zz = 0; zz < yy; zz++) {

            // If hit, clean out the double name
            if ([[sortedDummyArray objectAtIndex:oo] isEqualToString:[finalArray objectAtIndex:rr]]) {

               counter++;

               // Check if there is more than one of this name
               if (counter > 1) {
                   [finalArray removeObjectAtIndex:rr];
                   rr--;
                   counter--;
               }
            }
            rr++;
        }
        counter = 0;
        rr = 0;
    }

    // Save who is in the game

    AccessQuestionsDB *shufflePlayersFunction = [AccessQuestionsDB new];
    finalArray = [shufflePlayersFunction shufflePlayers: finalArray];
    [shufflePlayersFunction release];

    TempPlayersInTheGame *savePlayersInTheGame = [TempPlayersInTheGame new];
    [savePlayersInTheGame saveSelectedPlayers:finalArray];
    [savePlayersInTheGame release];

    [super viewDidDisappear:animated];
}

Но все это излишне только для удаления дублирующихся записей,преобразование вашего массива в NSSet (который всегда уникален), а затем преобразование его обратно в NSArray должно позаботиться об этом за вас, поэтому ваша функция должна быть :

- (void)viewDidDisappear:(BOOL)animated {

    // Empty array to be sure it is empty
    [playerArray removeAllObjects];

    //============CLEAN OUT DOUBLE NAMES FROM ARRAY==============//   
    NSSet *uniquePlayers = [NSSet setWithArray:selectedPlayersArray];

    // Save who is in the game

    AccessQuestionsDB *shufflePlayersFunction = [AccessQuestionsDB new];
    NSArray *finalArray = [shufflePlayersFunction shufflePlayers: [uniquePlayers allObjects]];
    [shufflePlayersFunction release];

    TempPlayersInTheGame *savePlayersInTheGame = [TempPlayersInTheGame new];
    [savePlayersInTheGame saveSelectedPlayers:finalArray];
    [savePlayersInTheGame release];

    [super viewDidDisappear:animated];
}
1 голос
/ 15 марта 2011

Ваша проблема в этой строке:

finalArray = [shufflePlayersFunction shufflePlayers: finalArray];

Ранее вы создавали новый массив в памяти и указывали finalArray, чтобы он указывал на него. Но эта строка здесь указывает finalArray, чтобы он указывал на что-то другое. Итак, теперь этот исходный массив, который вы создали, все еще находится в памяти, плюс вы освобождаете другой массив.

Вы также делаете то же самое с sortedDummyArray. Если вы выделяете объект, не устанавливайте указатель так, чтобы он указывал на что-то другое.

1 голос
/ 15 марта 2011

Требуется ли вызов для сохранения dummySortedArray?Я думаю, у вас уже может быть счет сохранения, когда вы инициализируете коллекцию

NSArray * sortedDummyArray = [[NSArray alloc] initWithArray: selectedPlayersArray];

...