122 votes

Profonde de la copie d'un NSArray

Est-il intégré dans la fonction qui me permet de faire une copie en profondeur un NSMutableArray?

Je regardai autour de moi, certaines personnes disent [aMutableArray copyWithZone:nil] fonctionne comme copie en profondeur. Mais j'ai essayé et il semble être une copie.

Maintenant je suis à la manuellement en faisant la copie avec un for boucle:

//deep copy a 9*9 mutable array to a passed-in reference array

-deepMuCopy : (NSMutableArray*) array 
    toNewArray : (NSMutableArray*) arrayNew {

    [arrayNew removeAllObjects];//ensure it's clean

    for (int y = 0; y<9; y++) {
        [arrayNew addObject:[NSMutableArray new]];
        for (int x = 0; x<9; x++) {
            [[arrayNew objectAtIndex:y] addObject:[NSMutableArray new]];

            NSMutableArray *aDomain = [[array objectAtIndex:y] objectAtIndex:x];
            for (int i = 0; i<[aDomain count]; i++) {

                //copy object by object
                NSNumber* n = [NSNumber numberWithInt:[[aDomain objectAtIndex:i] intValue]];
                [[[arrayNew objectAtIndex:y] objectAtIndex:x] addObject:n];
            }
        }
    }
}

mais j'aimerais un monde plus propre, plus succincte solution.

216voto

François P. Points 3580

Comme la Pomme docs de l'état,

Si vous avez seulement besoin d'un niveau de profondeur de copie, vous pouvez appeler explicitement pour l'un...

NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:oldArray copyItems:YES];

Le code ci-dessus crée un nouveau tableau dont les membres sont peu profondes des copies des membres de l'ancien tableau.

Notez que si vous avez besoin de profondément copier un ensemble de données imbriquées structure - ce lié Apple docs appeler une "vraie copie en profondeur" - ensuite, cette approche ne suffit pas à voir les autres réponses ici.

65voto

Andrew Grant Points 35305

Le seul moyen que je connaisse pour facilement faire cela est de l'archive, puis immédiatement à la réactivation de votre tableau. Il se sent comme un peu un hack, mais est en fait explicitement suggéré dans la Documentation d'Apple sur la copie des collections, qui stipule:

Si vous avez besoin d'une vrai copie en profondeur, comme lorsque vous avez un tableau de tableaux, vous pouvez archiver et puis réactivation de la collection, à condition que le contenu de tous conformes à la NSCoding protocole. Un exemple de cette technique est montré dans le Listing 3.

Le Listing 3 Une vrai copie en profondeur

NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:
          [NSKeyedArchiver archivedDataWithRootObject:oldArray]];

Le hic, c'est que votre objet doit prendre en charge la NSCoding interface, car il sera utilisé pour sauvegarder/charger les données.

35voto

C'est parce que l'appelant copy est le même que copyWithZone:NULL également connu comme la copie avec la zone par défaut. L' copy appel n'aboutit pas à une copie en profondeur. Dans la plupart des cas, il serait de vous donner une copie superficielle, mais en tout cas, il dépend de la classe. Pour une discussion approfondie je vous recommande les Collections des Sujets de Programmation sur le site des Développeurs Apple. Pour un niveau de profondeur de la copie, vous pouvez appeler:

NSArray *deepCopyArray = [[NSArray alloc] initWithArray:someArray copyItems:YES];

mais pour une vraie copie en profondeur (Tableau de Tableaux), vous devrez NSCoding et archiver/désarchiver l'objet:

NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:oldArray]];

5voto

Ben Zotto Points 32105

Non, il n'y a pas quelque chose de construit dans les cadres de cette. Cacao collections de soutien peu profondes des copies (avec l' copy ou arrayWithArray: méthodes) mais ne parle même pas d'une copie en profondeur concept.

C'est parce que "copie" commence à devenir difficile de définir le contenu de vos collections de démarrage, y compris vos propres objets personnalisés. Ne "copie" signifie chaque objet dans l'objet graphique est une référence unique par rapport à chaque objet dans l'objet d'origine graphique?

Si il y avait une hypothétique NSDeepCopying protocole, vous pouvez le configurer et à prendre des décisions dans l'ensemble de vos objets, mais malheureusement il n'y en a pas. Si vous contrôlé la plupart des objets dans votre graphique, vous pouvez créer ce protocole vous-même et le mettre en œuvre, mais vous auriez besoin d'ajouter une catégorie à la Fondation de classes nécessaires.

@AndrewGrant de réponse, ce qui suggère l'utilisation de incrusté d'archivage/désarchivage est un nonperformant mais correcte et propre façon de réaliser ce pour des objets arbitraires. Ce livre va même jusqu'donc suggérer l'ajout d'une catégorie à tous les objets est exactement ce que fait à l'appui de profondeur de la copie.

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