2012-02-06 5 views
0

J'ai un problème avec mon code que pour la vie de moi je ne peux pas comprendre, même pas avec tous les fils précédents ici sur SO. Je tire des données d'une source JSON et les place dans un NSDictionary comme indiqué dans les tutoriels et sur SO. Lors du profilage de l'application, je remarque une fuite de mémoire causée par ce NSDictionary mais le relâchant à la fin de cette fonction bloque l'application. Aucune suggestion? (Soit dit en passant: Je suis nouveau Obj-C et la programmation en général, de sorte que ce code est la plupart du temps cherrypicked provenant de diverses sources.)NSDictionary fuite de mémoire

- (void)fetchedData:(NSData *)responseData { 
    //parse JSON for empty return 
    if([responseData length] != 0){ 

     NSError* error = nil; 
     //Convert JSON data to Obj-C 
     NSDictionary* allShotData = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error]; 

     NSString *player = [[allShotData objectForKey:@"player"] objectForKey:@"name"]; 
     NSString *shotDribbblePage = [allShotData objectForKey:@"url"]; 

     NSString *shotTitle = [allShotData objectForKey:@"title"]; 
     NSURL *imageURL = [NSURL URLWithString:[allShotData objectForKey:@"image_url"]]; 
     shotPageURL = [shotDribbblePage retain]; 


     //*********************** 
     // Setup a-sync loading of shot 
     //*********************** 

     NSOperationQueue *queue = [NSOperationQueue new]; 
     NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadImage:) object:imageURL]; 
     [queue addOperation:operation]; 
     [operation release]; 
     [queue release]; 
    } 
    else{ 
     airballCount++; 
     if (airballCount <= 20) { 
      [self getDribbbleData]; 
     } 
     else{ 
      NSLog(@"Too many airballs. Bailing out"); 
      [self showNoConnectionModal]; 
     } 
    } 
} 

Répondre

2

ici:

shotPageURL = [shotDribbblePage retain]; 

vous devriez probablement utiliser l'accesseur:

self.shotPageURL = shotDribbblePage; 

Je vraiment souligner que vous devez utiliser votre accesseurs partout car ils font votre comptage ref fo r vous (exception: pas dans les initialiseurs et dealloc). Comme le note également le béryllium, vous pouvez faire votre compte manuellement s'il n'y a pas d'accesseur. Cela prend la forme de base:

[shotPageURL release]; 
shotPageURL = [shotDribbblePage retain]; 

Si c'est le contenu du dictionnaire retourné qui fuit, il est comment vous avez utilisé/référencé le contenu lors de la lecture (sur Retain).

Si vous utilisez votre classe dans un contexte simultané, vous aurez généralement besoin d'un verrou.

Si vous chargez un UIImage ou interagissez autrement avec des objets UIKit à partir d'un thread secondaire - ce n'est pas bon.

+1

Ou '[version shotPageURL]; shotPageURL = nil; shotPageURL = [shotDribbblePage conserve]; 's'il n'y a pas de propriété. – beryllium

+0

@beryllium noté - merci. – justin

+0

Merci Justin, c'était effectivement l'un des problèmes mais il s'avère que ce n'est pas le seul. Un gars a mentionné la copie de la shotDribbblePage en ajoutant une copie et en la relâchant manuellement par la suite. Cela a fait l'affaire apparemment que le pic rouge n'apparaît plus. –