2010-05-22 5 views
0

J'ai une question de débutant sur les points suivants:Pourquoi ce type de version ne fonctionne pas?

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
    NSArray *anArray; 
    anArray = [dictionary objectForKey: [NSString stringWithFormat:@"%d", section]]; 
    //here dictionary is of type NSDictionary, initialized in another place. 
    AnObject *obj = [[AnObject alloc] init]; 
    obj = [anArray objectAtIndex:0]; 
    [anArray release]; 
    return obj.title; 
} 

Si je cours comme il est j'obtenir une erreur. Si je ne mets pas [une version d'Array] cela fonctionne très bien. Je ne comprends pas très bien pourquoi cela se passe-t-il?

Merci.

+0

Ce que JeremyP a dit.Cependant, vous allouez aussi inutilement une instance de 'AnObject', puis vous la falsifiez sur la ligne suivante. – bbum

Répondre

2

Vous absolument devez lire et comprendre le Cocoa Memory Management Rules, en particulier la règle fondamentale qui stipule:

Vous prenez possession d'un objet si vous le créez à l'aide d'une méthode dont le nom commence par "alloc" ou "new" ou contient "copy" (par exemple, alloc, newObject ou mutableCopy), ou si vous lui envoyez un n message. Vous êtes responsable de renoncer à la propriété des objets que vous possédez en utilisant la libération ou autorelease. Toute autre fois que vous recevez un objet, vous devez et non le libérer.

Maintenant, regardez comment vous avez trouvé un tableau. Vous avez utilisé la méthode objectForKey: Elle ne commence pas par alloc, ni new, ni par copy. Vous n'avez pas non plus conservé un tableau. Par conséquent, vous ne possédez pas anArray. Vous ne devez pas le libérer.

La règle citée ci-dessus est la chose la plus importante à savoir sur la programmation avec Cocoa sur iPhone ou Mac sans récupération de place. Une des autres affiches ici est venu avec l'acronyme NARC (New Alloc Retain Copy) comme un aide-mémoire qui est assez pratique.

Appliquons la règle à la variable appelée obj dans votre code. Vous l'avez obtenu avec un appel à alloc, vous êtes donc responsable de le libérer. Cependant, vous l'avez ensuite obtenu (en écrasant la valeur précédente) avec un appel à objectForIndex: après cela, vous ne devez pas le libérer. Cependant, la première valeur a dû être libérée et a maintenant fui. en fait, la ligne alloc est inutile.

+0

Thnak vous, je comprends maintenant. – CristiC

+0

Légère inexactitude dans ma réponse. La règle citée est la chose la plus importante à savoir sur la programmation de Cocoa dans un environnement * non * GC (l'iPhone n'est pas GC). – JeremyP

1

Vous n'avez pas besoin de libérer anArray car vous ne le créez pas. Le dictionnaire vous donne juste un pointeur sur celui qu'il a.

Vous avez, semble-t-il, une fuite de mémoire dans laquelle vous créez l'objet AnObject. Sur la ligne suivante, vous réaffectez la variable "obj" à quelque chose que vous obtenez d'un tableau. Mais vous n'avez pas publié l'AnObject que vous avez créé sur la ligne ci-dessus.

Je pense que votre code devrait ressembler à ceci:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
    NSArray *anArray; 
    anArray = [dictionary objectForKey: [NSString stringWithFormat:@"%d", section]]; 
    //here dictionary is of type NSDictionary, initialized in another place. 
    obj = [anArray objectAtIndex:0]; 
    return obj.title; 
} 

Vous n'avez pas besoin de libérer ce que vous n'avez pas créé.

+0

Il semble que nous avons posté à peu près exactement la même réponse en même temps;) – Jasarien

1

anArray n'est pas alloué, conservé, copié ou modifié par vous, vous n'avez donc pas besoin de le libérer.

En outre, vous avez une fuite dans laquelle vous créez une nouvelle instance AnObject en utilisant alloc/init, mais vous lui attribuez une nouvelle valeur directement après, à partir du tableau.

Votre code devrait ressembler à:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
    NSArray *anArray; 
    anArray = [dictionary objectForKey: [NSString stringWithFormat:@"%d", section]]; 
    //here dictionary is of type NSDictionary, initialized in another place. 
    AnObject *obj = [anArray objectAtIndex:0]; 
    return obj.title; 
} 
+0

Il, vous le dites * n'était pas * une course :-) – drekka

Questions connexes