2010-12-01 39 views
0

Je viens juste de commencer à sauter dans le domaine de l'Objective-C et je commence tout doucement à l'obtenir. J'ai travaillé sur désarchiver un fichier qui était un NSMutableArray et initialiser dans mon modèle avec ce tableau. Le tableau est rempli avec divers NSMutableDicationary. D'après ce que j'ai vu, il va ajouter ces dictionnaires comme non mutables, alors je suis allé de l'avant et copié le régulier et les mettre dans un mutable et enlever l'ancien. Cette solution semble fonctionner pour tous les cas sauf le tout premier.NCSFDictionary, méthode de mutation envoyée à un objet immuable

Je ne sais pas pourquoi cela fonctionnerait pour tous, sauf le premier.

Voici comment j'initialisant tous

-(id) initWithList:(NSMutableArray *)savedList 
{ 
    self = [super init]; 
    if (self) 
    { 
     int size=0; 
     serverList=[[NSMutableArray alloc] initWithArray:savedList copyItems:YES]; 
     size=[serverList count]; 
     for(int i=0;i<size;i++) 
     { 
      loginList=[NSMutableDictionary dictionaryWithDictionary:[serverList objectAtIndex:i]]; 
      [serverList addObject:loginList]; 
      [serverList removeObjectAtIndex:i]; 
     } 
    } 
    return self; 
} 

Voici le code qui jette l'erreur, la valeur est lue d'une case à cocher dans un tableview et passé ici pour changer la valeur.

-(void)setMount:(int)row value:(NSNumber*)boolAsNumber 
{ 
    [[serverList objectAtIndex:row] setObject:boolAsNumber forKey:@"mountshare"]; 
} 

Voici l'erreur qu'il montre quand je tente de changer le premier élément

2010-12-01 13:38:54.445 Network Share[35992:a0f] *** -[NSCFDictionary setObject:forKey:]: mutating method sent to immutable object 

Merci pour votre aide. S'il y a un meilleur moyen s'il vous plaît faites le moi savoir.

Répondre

3

Ce code boucle est erroné:

size=[serverList count]; 
    for(int i=0;i<size;i++) 
    { 

     loginList=[NSMutableDictionary dictionaryWithDictionary:[serverList objectAtIndex:i]]; 
     [serverList addObject:loginList]; 
     [serverList removeObjectAtIndex:i]; 
    } 

Lorsque vous supprimez un objet, le tableau est renumérotés. Après avoir traité le 1er objet à l'index 0, le 2ème objet d'origine devient le 1er objet à l'index 0, mais i est maintenant défini sur l'index 1, où se trouve le 3ème objet d'origine! Cela signifie que vous ne traitez que des éléments alternatifs du tableau original, et que les articles 2, 4, etc. ne sont jamais échangés, et c'est pourquoi vous obtenez les erreurs que vous voyez. Une façon de résoudre ce problème serait de remplacer le "i" dans les appels objectAtIndex: et removeObjectAtIndex: par "0", de sorte que vous sortez toujours les éléments de l'avant du tableau.

La solution alternative serait de créer un tableau séparé newServerList et d'y insérer vos nouveaux objets. À la fin de la boucle, libérez l'ancienne liste serverList et définissez la variable pour qu'elle pointe vers newServerList.

+0

Wow merci! Cela l'explique, fonctionne comme un charme maintenant. – utahwithak

+0

merci ... +1 son résolu un problème aussi .. :) – Rajneesh071

+0

et j'ai répondu aussi .. en utilisant votre réponse .. :) http: // stackoverflow.com/questions/6100271/nsinternalinconsistencyexception-avec-nsuserdefaults-when-using-method-setvalue/13952939 # 13952939 – Rajneesh071

1

Vos index sont foirés. Dès que vous supprimez l'objet à l'index 0, le suivant prendra sa place et vous ne remplacera jamais, parce que vous ensuite poursuivre l'index 1.

{immutable0, immutable1} 

i = 0: 

addObject: 
{immutable0, immutable1, mutable0} 

removeObjectAtIndex: 
{immutable1, mutable0} 

i = 1: 

addObject: 
{immutable0, mutable0, mutable02} 

removeObjectAtIndex: 
{immutable0, mutable02} 

-> encore obtenu l'immuable il. N'oubliez pas de ne jamais supprimer des objets d'un tableau modifiable que vous parcourez en même temps.

Vous pouvez condenser un peu le code:

NSMutableArray *serverList = [NSMutableArray arrayWithCapacity:[savedList count]]; 
for (NSDictionary *dictionary in savedList) 
{ 
    mutable = [dictionary mutableCopy]; 
    [serverList addObject:mutable]; 
    [mutable release]; 
} 

Rien à voir avec votre problème: l'argument est évidemment faux (NSMutableArray), si vous vous attendez là un tableau immuable; et si vous créez votre serverList de cette façon, il n'y a pas besoin d'une copie profonde (copyItems: YES).