37 votes

Objective-C NSMutableArray a muté pendant l'énumération?

J'ai un peu tombé dans l'erreur lorsque vous essayez de supprimer des objets à partir d'un NSMutableArray tandis que d'autres objets est en train d'être ajouté à cela d'ailleurs. Pour faire simple, je n'ai aucune idée sur comment résoudre ce problème. Voici ce que j'ai fais:

J'ai 4 minuteries d'appel 4 méthodes différentes qui ajoute un objet à la même matrice. Maintenant, lorsque j'appuie sur un bouton de certaines, j'ai besoin de supprimer tous les objets dans le tableau (ou au moins certains). J'ai donc essayé d'abord invalider tous les 4 minuteries, puis faire le travail que je veux avec le tableau, et puis le feu jusqu'les compteurs à zéro. Je pensais que ce serait avez travaillé depuis que je ne suis pas en utilisant des minuteries plus à énumérer dans le tableau, mais apparemment ça ne fonctionne pas.

Toutes les suggestions ici?

110voto

deanWombourne Points 26066

Il n'a rien à voir avec vos compteurs. Parce que (je suppose) de votre minuteries fonctionnent tous sur le même thread que votre modification de la méthode que vous n'avez pas besoin de s'arrêter et de démarrer. iOS n'utilise pas une interruption de modèle pour les rappels de la minuterie, ils doivent attendre leur tour comme tout autre cas :)

Vous êtes probablement faire quelque chose comme

for (id object in myArray)
   if (someCondition)
       [myArray removeObject:object];

Vous ne pouvez pas modifier une mutable tableau pendant que vous allez à travers elle de sorte que vous besoin de faire un tableau temporaire de tenir les choses que vous voulez supprimer

// Find the things to remove
NSMutableArray *toDelete = [NSMutableArray array];
for (id object in myArray)
   if (someCondition)
       [toDelete addObject:object];

// Remove them
[myArray removeObjectsInArray:toDelete];

24voto

ferostar Points 4822

Vous pouvez le faire de cette façon:

 for (id object in [myArray copy])
   if (someCondition)
       [myArray removeObject:object];
 

Comme @deanWombourne a déclaré: "vous ne pouvez pas éditer un tableau mutable tant que vous le parcourez", je vais donc créer une copie auto-supprimée de votre tableau d'origine pour énumérer les objets, afin de pouvoir les supprimer en toute sécurité. tout ce que tu veux.

Plus clair et moins code de la chaudière (je pense!).

Mise à jour : Suppression de l'appel à libération automatique car il s'agissait d'une réponse ancienne, pré-ARC.

5voto

Niklas Berglund Points 975

Vous pouvez utiliser la directive @synchronized () pour verrouiller le tableau pendant sa mutation:

 if (someCondition) {
    @synchronized(yourArray) {
        [yourArray removeObject:someObject];
    }
}
 

Plus d'informations sur http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/Chapters/ocThreading.html

0voto

Basheer_CAD Points 2087

Utilisez cette énumération à la place:

 for(int i=0; i< self.myArr.count; i++)
{
     id obj = [self.myArr objectAtIndex:i];
     // do something with obj and then... 
     [self.myArr removeObject:obj];
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X