2009-03-25 10 views
2

La fonction que je suis à la recherche:Affectation des valeurs aux variables d'instance dans l'objectif C

-(void)viewDidLoad { 
    NSBundle *bundle = [NSBundle mainBundle]; 
    NSString *plistPath = [bundle pathForResource:@"statedictionary" ofType:@"plist"]; 

    NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath]; 
    self.statesZips = dictionary; 
    [dictionary release]; 

    NSArray *components = [self.stateZips allKeys]; 
    NSArray *sorted = [components sortedArrayUsingSelector:@selector(compare:)]; 
    self.States = sorted; 

    NSString *selectedState = [self.states objectAtIndex:0]; 
    NSArray *array = [stateZips objectForKey: selectedState]; 
    self.zips = array; 
} 

Pourquoi un NSDictionary alloué, puis affecté à un pointeur appelé * dictionnaire, puis affecté à la stateZips variable d'instance? Pourquoi ne pas l'allouer et l'affecter directement à la variable d'instance et économiser la mémoire de créer et libérer un autre NSDictionary? La même méthodologie est toujours suivie, y compris plus tard dans cette fonction avec le NSArray ...

NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath]; 
self.statesZips = dictionary; 
[dictionary release]; 

En outre, ce tri met les clés d'une table de hachage (dictionnaire) dans l'ordre alphabétique. Je ne suis pas sûr que je comprends cette ligne:

NSArray *sorted = [components sortedArrayUsingSelector:@selector(compare:)]; 

Répondre

6

Personne ne semble avoir abordé le fait que la ligne

self.statesZips = dictionary; 

est pas directement une instance affectation variable.stateZips est une propriété et cette ligne de code appelle la méthode setStateZips:. Cette méthode conserve ou copie le dictionnaire, donc à moins que la méthode viewDidLoad ait l'intention de l'utiliser à nouveau dans un but précis, elle n'est plus nécessaire. Cela le rend OK à release.

La ligne précédente:

[[NSDictionary alloc] initWithContentsOfFile:plistPath]; 

alloue un objet. Cela rend votre responsabilité à release une fois que vous n'en avez plus besoin. Après l'avoir affecté à la propriété statesZips, il n'est plus nécessaire, il est donc libéré et vous ne devez plus utiliser dictionary. Vous remarquerez que le code postérieur ne fait référence qu'à self.stateZips, et non à dictionary.

Dans le cas du NSArray plus tard dans la méthode, viewDidLoad n'alloue pas l'objet, de sorte que la méthode n'est pas chargée d'appeler release dessus. La règle générale est que si vous le faites, vous êtes responsable de vous assurer qu'il est libéré. Sinon, ce n'est pas votre problème.

Le tri de la baie utilise la méthode sortedArrayUsingSelector:. Un sélecteur identifie une méthode dans Objective-C. Et le @selector est la syntaxe littérale pour les sélecteurs (un peu comme comment @"" est la syntaxe littérale pour NSString objets). Donc, ce que dit ce code, c'est "donnez-moi un tableau où les objets de components sont triés, et utilisez la méthode compare: pour comparer chaque objet quand vous faites le tri. le tableau pour déterminer comment les mettre en ordre

+1

Je pense réellement que la sémantique retain/assign de la propriété statesZips Le code alloue un objet et doit donc le libérer, * indépendamment * de la sémantique de statesZips, à moins qu'elle ne soit exécutée dans un environnement récupéré par la corbeille. –

+0

@Barry Wark: bien, non. la sémantique des statesZips est très pertinente. si cette méthode ne conservait pas le dictionnaire ou ne le copiait pas, l'accès à statesZip après la ligne 7 entraînerait un comportement indéfini (probablement un segfault). – hop

+0

Les fonctions de commodité telles que initWithContentsOfFile sont libérées automatiquement. –

4

La propriété est statesZips probablement retenu, c'est le raisonnement. Lorsque NSDictionary est attribué pour la première fois, son nombre de rétention est de 1. Lorsqu'il est affecté à statesZips, le nombre de rétention devient 2. Lorsqu'il est libéré, le nombre de retards tombe à 1, ce qui correspond généralement au résultat souhaité.

Notez que le code ci-dessous aurait produit (presque) le même résultat:

self.statesZips = [NSDictionary dictionaryWithContentsOfFile:plistPath]; 

parce que dictionaryWithContentsOfFile renvoie un objet autoreleased. En tant que convention, les méthodes de classe telles que [NSDictionary dictionary] renvoient des objets libérés automatiquement (qui sont automatiquement libérés après un certain temps), tandis que la méthode alloc-init habituelle (comme dans [[NSDictionary alloc] init]) renvoie des objets conservés.

Je vous suggère de lire le Memory Management Programming Guide for Cocoa pour plus d'informations.

EDIT: Je dois avoir manqué la dernière partie de votre question quand je l'ai lu pour la première fois, mais Barry a déjà répondu à cette partie.

2

Ce code utilise la gestion de la mémoire comptée par référence (pas la gestion automatique de la mémoire de récupération de place disponible dans Objective-C 2.0 sous OS X). Lorsque tout objet (dans ce cas, le NSDictionary et le NSArray) sont alloués, l'appelant est responsable d'appeler -release sur cette instance. Ne pas appeler la libération provoque une fuite de mémoire. Le code aurait pu être écrit comme

self.statesZips = [[[NSDictionary alloc] initWithContentsOfFile:plistPath] autorelease]; 

mais au détriment de la gestion de la mémoire moins explicite (se fondant sur NSAutoreleasePool pour libérer l'instance alloc'd à la fin de la boucle d'événement itération.

l'appel

[components sortedArrayUsingSelector:@selector(compare:)]; 

retourne un tableau dont les éléments viennent de components mais en fonction de la valeur de retour d'appel [elem1 comparer: elem2]. comparer deux éléments de réseau

+0

+1 pour la bonne réponse à la question posée La sémantique de la propriété statesZip n'est pas pertinente ici La raison de ce modèle est la lisibilité du code et la gestion explicite de la mémoire Merci à Apple pour ARC afin que nous ayons de moins en moins de questions à ce sujet (j'imagine que l'accès aux questions sur les variables de bloc sont les nouvelles questions de conservation/publication) – ikuramedia

Questions connexes