2010-02-23 3 views
0

Selon l'analyse d'Instruments, j'ai une fuite de mémoire ici - et - je ne sais pas comment libérer correctement l'objet scoresArray que j'ai créé.Libération d'un objet tableau

Ce code fonctionne correctement, à l'exception de la fuite. Je libère l'objet highScoresArray plus tard dans le code - mais tente de libérer le scoreArray tuer l'application. Je pensais que lorsque je publierais highScoresArray, je publierais scoresArray, car ils pointent tous les deux vers le même emplacement en mémoire. Si quelqu'un peut indiquer où ma pensée est imparfaite, ce serait génial.

- (void) readScoresFile { 
    // Read the Scores File, if it exists 
    NSString *filePath = [self scoresFilePath]; 
    // Only load the file if it exists at the path 
    if ([[NSFileManager defaultManager] fileExistsAtPath: filePath]) { 
     scoresFileExistsFlag = YES; 
     NSLog(@"SCORES FILE EXISTS - THEREFORE LOAD IT"); 
     NSMutableArray *scoresArray = [[NSMutableArray alloc] initWithContentsOfFile: filePath]; 
     highScoresArray = scoresArray; 
    } else { 
     scoresFileExistsFlag = NO; 
     NSMutableArray *scoresArray = [[NSMutableArray alloc] init]; 
     highScoresArray = scoresArray; 

     // No Scores File exists - we need to create and save an empty one. 
     int counter = 1; 
     while (counter <= 5) { 
      // Set up a date object and format same for inclusion in the Scores file 
      NSDate *now = [[NSDate alloc] init]; 
      NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; 
      [dateFormat setDateFormat:@"yyyy.MM.dd"]; 
      NSString *theDateNow = [dateFormat stringFromDate:now]; 
      // Add the score data (Score and User and date) to the runScoreDataDictionary 
      runScoreDataDictionary = [NSDictionary dictionaryWithObjectsAndKeys: 
       [NSNumber numberWithInt:0], @"score", 
       [NSNumber numberWithInt:0], @"landings", 
       currentUser, @"user", 
       theDateNow, @"date", nil]; 
      //NSLog(@"Dictionary contains: %@", runScoreDataDictionary); 
      // Add the dictionary to the highScoreArray 
      [highScoresArray addObject:runScoreDataDictionary]; 
      //NSLog(@"OBJECTS in ARRAY: %i", [highScoresArray count]); 

      [self writeScoresFile]; // Write the empty scores file to disk 

      [now release]; 
      [dateFormat release]; 

      ++counter; 

      //[scoresArray release]; // TESTING TO SEE IF THIS KILLS - YES KILLS 
     } 
    } 
} 

Répondre

1

Je suppose que highScoresArray est une variable d'instance (puisqu'elle n'est déclarée nulle part dans la méthode que vous avez listée). Cela signifie que lors de la création de scoresArray (qui est le même objet que highScoresArray) il a un nombre de retenue de 1. Vous ne le faites pas retain, alors release il décrémentera son nombre de retenue à 0 et il sera nettoyé - pas une bonne chose pour une variable d'instance.

Je suis aussi ne sais pas pourquoi vous faites ceci:

NSMutableArray *scoresArray = [[NSMutableArray alloc] init]; 
highScoresArray = scoresArray; 

Vous ne semblez pas avoir besoin d'utiliser scoresArray partout ailleurs, vous pouvez donc le faire:

[highScoresArray release]; // Release the old object 
highScoresArray = [[NSMutableArray alloc] init]; 
+0

Oui - highScoresArray est une variable d'instance - j'ai éliminé le scorehorsArray - merci pour l'entrée. – ReachWest

1

je libère l'objet highScoresArray plus tard dans le code - mais les tentatives pour libérer le tuer scoresArray l'application. Je pensais que quand je sorti highScoresArray, que je libérer scoresArray, car ils pointent tous deux au même endroit dans la mémoire

Tant que vous ne l'avez pas changé le pointeur highScoresArray pour pointer vers un autre objet, libérant ce sera la même chose que de libérer scoresArray.

NSMutableArray* highScoresArray; 
NSMutableArray* scoresArray = [[NSMutableArray alloc] init]; 
highScoresArray = scoresArray; 
[highScoresArray release]; // same as `[scoresArray release];` 

Mais si vous changez l'un d'eux par la suite à un point à un autre objet, de les libérer ne seront pas équivalentes:

NSMutableArray* highScoresArray; 
NSMutableArray* scoresArray = [[NSMutableArray alloc] init]; 
highScoresArray = scoresArray; 
// ... Now make `highScoresArray` point to another object ... 
highScoresArray = [[NSMutableArray alloc] init]; 
// Now you should release both as they point to different objects. 
[highScoresArray release]; 
[scoresArray release]; 

Bien sûr, appeler simplement addObject ne modifie pas le pointeur . Il change l'objet pointé sur. Seule la réaffectation du pointeur à un autre objet est importante ici.

+0

Merci très beaucoup pour votre aide. – ReachWest