2011-05-25 3 views
0

J'ai une application universelle dont la partie iPad utilise un UIPopoverController qui affiche un UIViewController partagé avec la partie iPhone. Lorsque la version iPhone charge et libère le contrôleur de vue, tout va bien (pas de fuite de mémoire). Lorsque la version iPad le charge, deux éléments, un NSDictionary et une fuite NSArray.UIPopoverController Memory Leak

Dans le contrôleur de vue, les deux objets sont créés et dealloc ainsi

- (void)setupModels { 
    fonts = [[NSDictionary alloc] initWithObjectsAndKeys: 
      @"Baskerville", @"Baskerville", 
      @"Georgia", @"Georgia", 
      @"HelveticaNeue", @"Helvetica Neue", 
      @"Palatino-Roman", @"Palatino Roman", 
      @"Verdana", @"Verdana", nil]; 

    fontNameKeys = [[NSArray alloc] initWithObjects: 
        @"Baskerville", 
        @"Georgia", 
        @"Helvetica Neue", 
        @"Palatino Roman", 
        @"Verdana", nil]; 
} 

- (void)dealloc { 
    [fonts release], fonts=nil; 
    [fontNameKeys release], fontNameKeys=nil; 

    [super dealloc]; 
} 

La version iPad crée et REJETTE la UIPopoverController ainsi

- (void)displaySettingsPopover:(id)sender { 
    if([self.settingsPopover isPopoverVisible]) { 
     //close the popover view if toolbar button was touched again and popover is already visible 
     //Thanks to @chrisonhismac 
     [self.settingsPopover dismissPopoverAnimated:YES]; 
     [self.settingsPopover.delegate popoverControllerDidDismissPopover:self.settingsPopover]; 
    } else { 
     if (!self.settingsPopover) { 
      //build our custom popover view 
      PreferencesViewController_iPhone *pvc = [[PreferencesViewController_iPhone alloc] initWithNibName:nil 
                             bundle:nil 
                           callbackObject:self 
                            selector:@selector(applySettingsFromPopover)]; 
      [pvc.view setBackgroundColor:[UIColor lightGrayColor]]; 
      [pvc.navigationItem setTitle:@"Preferences"]; 
      [pvc setContentSizeForViewInPopover:CGSizeMake(320, 444)]; 

      //create a popover controller 
      self.settingsPopover = [[UIPopoverController alloc] initWithContentViewController:pvc]; 
      [pvc release]; 
      self.settingsPopover.delegate = self; 
     } 

     //present the popover view non-modal with a 
     //refrence to the toolbar button which was pressed 
     [self.settingsPopover presentPopoverFromBarButtonItem:sender 
            permittedArrowDirections:UIPopoverArrowDirectionUp 
                animated:YES]; 
    } 
} 

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController { 
    [self.settingsPopover setDelegate:nil]; 
    [settingsPopover release]; 
    settingsPopover=nil; 
} 

Je ne sais pas pourquoi le NSDictionary et la NSArray fuient pour l'iPad mais pas pour l'iPhone. Le Profiler dit que leur nombre de retenues est initialement fixé à 1 mais n'est jamais déséquilibré.

Merci!

+0

En passant, vous pouvez supprimer cet appel manuel au délégué. Cela ne devrait pas être fait. –

+0

Sans cette ligne, popoverControllerDidDismissPopover: n'est pas appelé lorsque l'utilisateur clique sur le bouton de la barre d'outils pour fermer le popover. Il est seulement appelé quand l'utilisateur clique loin du popover. Peut-être y a-t-il une meilleure façon de gérer cela? J'ai suivi un exemple d'un autre article. – TimN

Répondre

4

Cette ligne fuites:

self.settingsPopover = [[UIPopoverController alloc] initWithContentViewController:pvc]; 

si votre settingsPopover est une propriété retain ou copy, retain étant très probable. Vérifiez de nouveau que, si c'est effectivement le cas, autorelease le comme:

self.settingsPopover = [[[UIPopoverController alloc] initWithContentViewController:pvc] autorelease]; 
+0

Merci, je vais essayer ça. – TimN

+0

Malheureusement, l'autorelease n'a pas aidé. Lorsque le popover est rejeté/libéré, le dictionnaire et le tableau ne sont pas libérés. BTW, j'ai ajouté un NSLog() au dealloc: pour vérifier qu'il est appelé quand le popover est libéré, et il est. Je pense que je pourrais rendre ces deux objets mutables et retirer leur contenu dans le dealloc, mais cela ne semble pas être nécessaire. – TimN

+0

En outre, leurs définitions de @property sont (si utile) 'propriétés @property (nonatomic, retain) NSDictionary *; @property (nonatomic, retain) NSArray * fontNameKeys; ' – TimN