¿Cómo convierto NSMutableArray a NSArray en C objetivo?
NSArray *array = mutableArray;
¿Cómo convierto NSMutableArray a NSArray en C objetivo?
NSArray *array = mutableArray;
Respuestas:
NSArray *array = [mutableArray copy];
Copy
hace copias inmutables Esto es bastante útil porque Apple puede hacer varias optimizaciones. Por ejemplo, enviar copy
a una matriz inmutable solo retiene el objeto y lo devuelve self
.
Si no usa recolección de basura o ARC recuerde que -copy
retiene el objeto.
copy
crea un NSArray normal y no un NSMutableArray?
NSArray
y NSMutableArray
, NSString
y NSMutableString
. Pero no, por ejemplo, NSViewController
que siempre contiene un estado mutable.
Una NSMutableArray
es una subclase de, NSArray
por lo que no siempre necesitará convertir, pero si desea asegurarse de que la matriz no se puede modificar, puede crear una NSArray
de estas formas dependiendo de si desea que se lance automáticamente o no:
/* Not autoreleased */
NSArray *array = [[NSArray alloc] initWithArray:mutableArray];
/* Autoreleased array */
NSArray *array = [NSArray arrayWithArray:mutableArray];
EDITAR: La solución proporcionada por Georg Schölly es una mejor manera de hacerlo y mucho más limpia, especialmente ahora que tenemos ARC y ni siquiera tenemos que llamar a autorelease.
Me gustan las dos soluciones principales:
NSArray *array = [NSArray arrayWithArray:mutableArray];
O
NSArray *array = [mutableArray copy];
La principal diferencia que veo en ellos es cómo se comportan cuando mutableArray es nulo :
NSMutableArray *mutableArray = nil;
NSArray *array = [NSArray arrayWithArray:mutableArray];
// array == @[] (empty array)
NSMutableArray *mutableArray = nil;
NSArray *array = [mutableArray copy];
// array == nil
[mutableArray copy]
puede simplificarse a [nil copy]
. En el objetivo-c, cualquier mensaje enviado a nil siempre será nil. Es importante recordar la distinción entre "nada" y "una matriz que no contiene nada".
intentas este código ---
NSMutableArray *myMutableArray = [myArray mutableCopy];
y
NSArray *myArray = [myMutableArray copy];
A continuación se muestra la forma de convertir NSMutableArray a 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;
En Swift 3.0 hay un nuevo tipo de datos Array . Declarar Array usando la let
palabra clave, entonces se convertiría en NSArray Y si declara usar la var
palabra clave, entonces se convertirá en NSMutableArray .
Código de muestra:
let newArray = oldArray as Array
En el objetivo-c:
NSArray *myArray = [myMutableArray copy];
En rápido:
var arr = myMutableArray as NSArray
NSArray *array = mutableArray;
Esta [mutableArray copy]
antipatrón está en todo el código de muestra. Deje de hacerlo para arreglos mutables desechables que son transitorios y se desasignan al final del alcance actual.
No hay forma de que el tiempo de ejecución pueda optimizar la copia innecesaria de una matriz mutable que está a punto de quedar fuera de alcance, decrementada a 0 y desasignada para siempre.
NSMutableArray
a una NSArray
variable no la convertirá (de eso se trata la pregunta del OP). Exponer dicho valor (por ejemplo, como un valor de retorno o como una propiedad) podría resultar en problemas muy difíciles de depurar si ese valor fue mutado inesperadamente. Esto se aplica a las mutaciones internas y externas ya que el valor mutable se comparte.
NSMutableArray
variable es suficiente. Dado que el objeto nunca dejó de ser una matriz mutable, invocar métodos de mutación tendrá éxito y mutará los datos compartidos. Si, por otro lado, se copió la matriz mutable original (cambiándola a una matriz inmutable) y luego se la asignó a una NSMutableArray
variable y se le solicitaron métodos de mutación, esas llamadas fallarían con doesNotRespondToSelector
errores porque el objeto que recibió la llamada al método de mutación está en hecho inmutable y no responde a esos métodos.
Si está construyendo una matriz a través de la mutabilidad y luego desea devolver una versión inmutable, simplemente puede devolver la matriz mutable como un "NSArray" a través de la herencia.
- (NSArray *)arrayOfStrings {
NSMutableArray *mutableArray = [NSMutableArray array];
mutableArray[0] = @"foo";
mutableArray[1] = @"bar";
return mutableArray;
}
Si "confía" en la persona que llama para tratar el objeto devuelto (técnicamente aún mutable) como un NSArray inmutable, esta es una opción más barata que [mutableArray copy]
.
Para determinar si puede cambiar un objeto recibido, el receptor de un mensaje debe confiar en el tipo formal del valor de retorno. Si recibe, por ejemplo, un objeto de matriz escrito como inmutable, no debe intentar mutarlo . No es una práctica de programación aceptable determinar si un objeto es mutable en función de su pertenencia a clases.
La práctica anterior se analiza con más detalle aquí:
Mejor práctica: Devuelva mutableArray.copy o mutableArray si el tipo de retorno es NSArray
estaba buscando la respuesta en swift 3 y esta pregunta se mostró como primer resultado en la búsqueda y me inspiró la respuesta, así que aquí está el código de swift 3
let array: [String] = nsMutableArrayObject.copy() as! [String]
NSArray *array = [mutableArray copy];