Comment convertir NSMutableArray en NSArray dans objectif c?
NSArray *array = mutableArray;
Comment convertir NSMutableArray en NSArray dans objectif c?
NSArray *array = mutableArray;
Réponses:
NSArray *array = [mutableArray copy];
Copy
fait des copies immuables. C'est très utile car Apple peut effectuer diverses optimisations. Par exemple, l'envoi copy
à un tableau immuable ne conserve que l'objet et retourne self
.
Si vous n'utilisez pas le ramasse-miettes ou ARC, n'oubliez pas que -copy
conserve l'objet.
copy
créent un NSArray normal et non un NSMutableArray?
NSArray
& NSMutableArray
, NSString
& NSMutableString
. Mais pas par exemple NSViewController
qui contient toujours un état mutable.
An NSMutableArray
est une sous-classe de NSArray
donc vous n'aurez pas toujours besoin de convertir, mais si vous voulez vous assurer que le tableau ne peut pas être modifié, vous pouvez créer l'une NSArray
ou l'autre de ces façons selon que vous souhaitez qu'il soit libéré automatiquement ou non:
/* Not autoreleased */
NSArray *array = [[NSArray alloc] initWithArray:mutableArray];
/* Autoreleased array */
NSArray *array = [NSArray arrayWithArray:mutableArray];
EDIT: La solution fournie par Georg Schölly est une meilleure façon de le faire et beaucoup plus propre, surtout maintenant que nous avons ARC et que nous n'avons même plus besoin d'appeler la libération automatique.
J'aime les deux solutions principales:
NSArray *array = [NSArray arrayWithArray:mutableArray];
Ou
NSArray *array = [mutableArray copy];
La principale différence que je vois en eux est la façon dont ils se comportent lorsque mutableArray est nul :
NSMutableArray *mutableArray = nil;
NSArray *array = [NSArray arrayWithArray:mutableArray];
// array == @[] (empty array)
NSMutableArray *mutableArray = nil;
NSArray *array = [mutableArray copy];
// array == nil
[mutableArray copy]
peut être simplifié en [nil copy]
. Dans objective-c, tout message envoyé à nil sera toujours nul. Il est important de se rappeler la distinction entre "rien" et "un tableau sans rien".
vous essayez ce code ---
NSMutableArray *myMutableArray = [myArray mutableCopy];
et
NSArray *myArray = [myMutableArray copy];
Vous trouverez ci-dessous un moyen de convertir NSMutableArray en NSArray:
//oldArray is having NSMutableArray data-type.
//Using Init with Array method.
NSArray *newArray1 = [[NSArray alloc]initWithArray:oldArray];
//Make copy of array
NSArray *newArray2 = [oldArray copy];
//Make mutablecopy of array
NSArray *newArray3 = [oldArray mutableCopy];
//Directly stored NSMutableArray to NSArray.
NSArray *newArray4 = oldArray;
Dans Swift 3.0, il existe un nouveau type de données Array . Déclarez Array en utilisant un let
mot-clé, il deviendrait NSArray. Et si vous déclarez en utilisant un var
mot-clé, il deviendrait NSMutableArray .
Exemple de code:
let newArray = oldArray as Array
Dans l'objectif-c:
NSArray *myArray = [myMutableArray copy];
En bref:
var arr = myMutableArray as NSArray
NSArray *array = mutableArray;
Cet [mutableArray copy]
antipattern est partout dans l'exemple de code. Arrêtez de le faire pour les tableaux mutables jetables qui sont transitoires et qui sont désalloués à la fin de la portée actuelle.
Il n'y a aucun moyen que le runtime optimise la copie inutile d'un tableau mutable qui est sur le point de sortir de la portée, décréfé à 0 et désalloué pour de bon.
NSMutableArray
à une NSArray
variable ne le convertira pas (c'est la question du PO). L'exposition d'une telle valeur (par exemple en tant que valeur de retour ou en tant que propriété) pourrait entraîner des problèmes de débogage très difficiles si cette valeur était modifiée de manière inattendue. Cela s'applique aux mutations internes et externes, car la valeur mutable est partagée.
NSMutableArray
variable. Étant donné que l'objet n'a jamais cessé d'être un tableau mutable, l'appel de méthodes de mutation réussira et mutera les données partagées. Si, d'autre part, le tableau mutable d'origine était copié - en le changeant en un tableau immuable - puis assigné à une NSMutableArray
variable et que des méthodes de mutation y étaient appelées, ces appels échoueraient avec des doesNotRespondToSelector
erreurs car l'objet qui a reçu l'appel de méthode de mutation est dans fait immuable et ne répond pas à ces méthodes.
Si vous construisez un tableau via la mutabilité et que vous souhaitez ensuite retourner une version immuable, vous pouvez simplement retourner le tableau mutable en tant que "NSArray" via l'héritage.
- (NSArray *)arrayOfStrings {
NSMutableArray *mutableArray = [NSMutableArray array];
mutableArray[0] = @"foo";
mutableArray[1] = @"bar";
return mutableArray;
}
Si vous "faites confiance" à l'appelant pour traiter l'objet de retour (techniquement encore modifiable) comme un NSArray immuable, c'est une option moins coûteuse que [mutableArray copy]
.
Pour déterminer s'il peut modifier un objet reçu, le destinataire d'un message doit s'appuyer sur le type formel de la valeur de retour. S'il reçoit, par exemple, un objet tableau typé immuable, il ne doit pas tenter de le muter . Ce n'est pas une pratique de programmation acceptable de déterminer si un objet est modifiable en fonction de son appartenance à la classe.
La pratique ci-dessus est discutée plus en détail ici:
Meilleure pratique: renvoyer mutableArray.copy ou mutableArray si le type de retour est NSArray
NSArray *array = [mutableArray copy];