2010-03-19 8 views
0

J'utilise la méthode suivante dans mon code:[Communiqué CFArray]: message envoyé à l'instance désallouées

- (NSMutableArray *) newOrderedArray:(NSMutableArray *)array ByKey:(NSString *)key ascending:(BOOL)ascending { 

    NSSortDescriptor *idDescriptor = [[NSSortDescriptor alloc] initWithKey:key ascending:ascending]; 

    NSArray *sortDescriptors = [NSArray arrayWithObject:idDescriptor]; 
    NSArray *orderArray = [array sortedArrayUsingDescriptors:sortDescriptors]; 

    [idDescriptor release]; 

    NSMutableArray *result = [NSMutableArray arrayWithArray:orderArray]; 

    return result; 
} 

Est-ce une méthode pratique bien codé? Comme je pense, il renvoie un NSMutableArray autoreleased.

Cette méthode est appelée par un autre:

- (id) otherMethod { 

    NSMutableArray *otherResult = [[[NSMutableArray alloc] initWithCapacity:[otherArray count]] autorelease]; 

    // I add some stuff to otherResult and then... 

    NSMutableArray *result = [dbUtils newOrderedArray:otherResult ByKey:@"objectId" ascending:NO]; 
    return result; 
} 

Cette méthode (otherMethod) est appelé dans certains contrôleur de vue où je veux stocker tableau retourné et relâchez quand désaffecter le contrôleur de vue. Cependant, lorsque [résultat retain] est appelé dans ce contrôleur de vue (parce que je besoin d'être disponible et je ne peux pas lui permettre d'être désallouée) Je reçois l'erreur suivante:

[CFArray release]: message sent to deallocated instance

J'ai essayé de log [result retainCount] juste avant d'appeler conserver et imprimer "1". Je ne comprends pas pourquoi une erreur est levée lors de l'appel de retain.

Merci,

A

Répondre

0

Je ne vois rien techniquement faux avec le code ci-dessus-- otherMethod devrait retourner un NSMutableArray autoreleased. Êtes-vous sûr de recevoir l'erreur lors de l'appel à conserver? Il semble plutôt que vous pourriez être en train d'envoyer une version à un moment donné au lieu de la conserver.

Stylistiquement, il y a une chose - avec des méthodes « nouveau » dans le titre doit toujours retourner non objets -autoreleased, vous devez soit le nom de votre méthode quelque chose d'autre (comme orderedArray...) ou utiliser [[NSMutableArray alloc] initWithArray:] au lieu de arrayWithArray. En outre, les signatures de méthode ne doit pas commencer par un capital (si ByKey devrait être byKey.

+0

Vous avez raison, le problème n'était pas sur le message conservé, c'était dans l'assignation self.array = result parce que dans un endroit précédent j'assignais en utilisant array = result (sans utiliser self) – arielcamus

0

essayez ceci:

NSMutableArray *otherResult = [[NSMutableArray initWithCapacity:[otherArray count]]; 

Parce que initWithCapacity retourne un tableau autoreleased. En ce moment vous dites à Autoreleasepool de libérer le tableau deux fois.

+0

'initWithCapacity:' ne retourne pas un objet autoreleased – Wevah

0

initWithCapacity:does not return an autoreleased object. – Wevah

AFAIK initWithCapacity est un initializier de commodité, qui par retour de convention objets autoreleased. Donc, si l'objet est utilisé uniquement dans une méthode locale

+2

Vous pensez à 'arrayWithCapacity'.' initWithCa pacity' est un initialiseur qui ne devrait être utilisé que dans le cadre de [[NSMutableArray alloc] initWithCapacity:] ', sinon vous obtiendrez un crash (je pense) - alloc retourne un objet non autoreleased, donc le nombre de retain est 1. – shosti

+0

eman est correct. Vous deux ("utile" pour la connaissance, eman pour la certitude) devrait lire les règles de gestion de la mémoire: http://developer.apple.com/mac/library/documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html –

Questions connexes