2010-07-20 8 views
2

Alors, je suis chargement par fichier et il contient XIB un ensemble de UIBarButtonItems. Certains éléments sont utilisés lorsque le viewDidLoad: est appelé.IBOutlets inutilisés qui fuient

@interface MyViewController : UIViewController { 

    IBOutlet UIBarButtonItem *addButton; 
    IBOutlet UIBarButtonItem *editButton; 
    IBOutlet UIBarButtonItem *doneButton; 
} 

// NB: There are no properties retaining anything. 

@end 

@implementation MyViewController 

- (void)viewDidLoad { 

    [super viewDidLoad]; 

    NSArray *initialToolbarItems = 
    [[NSArray alloc] initWithObjects: addButton, editButton, nil]; 

    self.toolbarItems = initialToolbarItems; 
    [initialToolbarItems release]; 
} 

- (void)dealloc { 
    [super dealloc]; 

    // Nothing else to do here since we are not retaining anything. 
    // … or are we? <insert dramatic music here> 
} 

@end 

Si je pousse le dessus du ViewController ci-dessus sur un tout UINavigationController semble bien, tous les IBOutlets sont assignés et se comportent comme prévu.

L'instant où j'applique le ViewController à la pile de navigation Les fuites d'instruments indiquent que je fuis un UIBarButtonItem. Pauvre de moi!

Si je change dealloc: à

- (void)dealloc { 
    [doneButton release]; 
    [super dealloc]; 
} 

pas de fuites se produisent. La même chose si j'utilise doneButton dans viewDidLoad:

NSArray *initialToolbarItems = 
    [[NSArray alloc] initWithObjects: addButton, editButton, doneButton, nil]; 

Ma question: Pourquoi mon IBOutlet fuit quand je ne l'utilise pas. Je ne le retiens à aucun moment. Le chargeur NIB devrait posséder l'objet, non?

+1

BTW: [super dealloc]; va dernière – willcodejavaforfood

+0

Droit vous êtes @willcodejavaforfood qui ne change pas la fuite si. –

+0

pas juste dire :) – willcodejavaforfood

Répondre

2

La seule chose que je peux penser:

Le nib loader traite les IBOutlets comme des références fortes. Tous les points de vente sont conservés par défaut, à moins que vous n'indiquiez spécifiquement assigner. Vous devez donc les libérer dans dealloc et viewDidUnload.

Vous pouvez également utiliser une propriété assignée pour en faire une référence faible:

@property (nonatomic, assign) IBOutlet UIBarButtonItem *doneButton; 

Quelques lectures: http://weblog.bignerdranch.com/?p=95

+0

L'ajout d'une propriété avec 'assign' supprime la fuite. Merci! Ceci, d'un autre côté, n'explique pas pourquoi la sortie est libérée correctement quand je l'utilise réellement, par ex. comme dans le dernier code ci-dessus. Cela suggérerait que UINibLoading ne libère ses «prises retenues» que lorsqu'elles sont retenues par quelque chose d'autre! Comment compliqué! Je n'ai pas eu l'occasion de lire tout l'article auquel vous étiez lié, mais vous semblez avoir mis le doigt sur la tête! Comme c'est cruel d'Apple de me forcer à écrire des propriétés quand je ne veux pas. :. ( –

+0

_Une mise à jour pour toute personne ayant la même problem._ Il y a deux solutions au problème 1 # Toujours soit pour faire des propriétés avec 'retain' chaque sortie et les mettre à' 'nil' dans -viewDidUnload..: 'et libérez l'ivar dans' -dealloc: '.Si vous définissez la propriété sur 'assign', vous devrez vous assurer que la sortie est chargée quand vous voulez l'utiliser! # 2 Ou, comme je le fais, et ne font pas de propriétés pour les points de vente, sauf si vous en avez vraiment besoin. Ensuite, dans '-viewDidUnload:' do '[myOutlet release], myOutlet = nil;' et '-dealloc:' do '[myOutlet release]'. À la fin ce sera moins de code. –

0

Si vous avez @property avec (conserver) déclarée pour les vos IBOOutlets ils seront conservés et doivent être libérées

+0

Je n'ai pas de propriété qui la conserve. Le code est comme vous le voyez ci-dessus. –

-1

Le tableau les retient

+0

OK, je ne suis pas sûr à 100% à ce sujet. Quelle propriété avez-vous pour toolbarItems? Je pense que vous avez retenu. Ajoutez simplement [release toolbarItems] dans dealloc – tadejsv

+1

En effet, c'est le cas, mais le tableau toolbarItems est une propriété de UIViewController. Il est pris en charge par l'appel à [super dealloc], et il libère le tableau qu'il crée. – jergason

+0

Oui, il le fait, mais lorsque la propriété 'toolbarItems' est libéré par' [dealloc super] ',' libération: 'a appelé à chacun des enfants de tableaux. En tout cas cela n'explique pas pourquoi c'est seulement quand le 'IBOutlet' est inutilisé que le problème se produit. –

Questions connexes