NSMutableArray addObject est défini sur zéro après la publication de l'objet

J'ai déclaré un NSMutableArray * arrAllRecordsM et j'essaie d'y ajouter NSMutableDictionary * dicRecordM en utilisant addObject . Le dicRecordM est ajouté à arrAllRecordsM mais en faisant [dicRecordM removeAllObjects] il est défini sur arrAllRecordsM . Voici le code, s'il vous plaît aidez-moi à le réparer.

self.arrAllRecordsM = [NSMutableArray array];
self.dicRecordM = [NSMutableDictionary dictionary];

// Une méthode

[self.dicRecordM setObject:@"Test" forKey:@"ADDRESS"];
[self.arrAllRecordsM addObject:self.dicRecordM];

// Value: Test
NSLog(@"Value: %@", [[self.arrAllRecordsM objectAtIndex:0] valueForKey:@"ADDRESS"]);
[self.dicRecordM removeAllObjects];

// Value: null
NSLog(@"Value: %@", [[self.arrAllRecordsM objectAtIndex:0] valueForKey:@"ADDRESS"]); 
0
Votre code se comporte correctement. Pourquoi attendez-vous un résultat différent? Vous essayez d'obtenir une valeur inexistante. Bien sûr, ça va retourner nil .
ajouté l'auteur rmaddy, source

2 Réponses

Ajouter un objet à un NSMutableArray ne stocke qu'un pointeur (ou "référence forte") à l'objet dans le tableau. Donc

[self.arrAllRecordsM objectAtIndex:0]

et

self.dicRecordM

sont deux pointeurs vers le même objet . Si vous supprimez toutes les paires clé/valeur de self.dicRecordM alors [self.arrAllRecordsM objectAtIndex: 0] pointe toujours vers la même (maintenant vide) dictionnaire. C'est la raison pour laquelle

[[self.arrAllRecordsM objectAtIndex:0] valueForKey:@"ADDRESS"]

renvoie nil .

Si vous voulez une copie indépendante du dictionnaire dans le tableau, utilisez

[self.arrAllRecordsM addObject:[self.dicRecordM copy]];

copy can be used on many classes, such as NSDictionary, NSArray et NSString et their mutable variants, to get a "functionally independent object". Formally, it is available for all classes conforming to the NSCopying protocol.

0
ajouté

C'est un comportement attendu. Vous avez supprimé tous les objets du dictionnaire en appelant removeAllObjects , puis vous avez essayé de récupérer un objet et d'obtenir nil , car il n'existe plus dans le dictionnaire ( vous l'avez enlevé).

Ce qui n'est peut-être pas clair pour vous, c'est que NSArray ne copie pas l'élément que vous y ajoutez, mais qu'il contient simplement une référence forte.

Ainsi, dicRecordM et arrAllRecordsM contiennent une référence à l'objet same , donc toute modification (dans ce cas removeAllObjects </> code>) affectera le même dictionnaire.


Incidemment, vous ne devriez pas utiliser valueForKey: pour accéder aux entrées du dictionnaire. Utilisez objectForKey: ou la syntaxe indicée plus courte. Par exemple

self.arrAllRecordsM[0][@"ADDRESS"]

Vous pouvez lire cette réponse Différence entre objectForKey et valueForKey? comme référence, mais la principale Le problème est que valueForKey: peut se comporter très différemment de objectForKey: si la clé contient des caractères KVC spéciaux, tels que @ ou . .

0
ajouté