How do I convert NSMutableArray to NSArray?
Solution 1
NSArray *array = [mutableArray copy];
Copy
makes immutable copies. This is quite useful because Apple can make various optimizations. For example sending copy
to a immutable array only retains the object and returns self
.
If you don't use garbage collection or ARC remember that -copy
retains the object.
Solution 2
An NSMutableArray
is a subclass of NSArray
so you won't always need to convert but if you want to make sure that the array can't be modified you can create a NSArray
either of these ways depending on whether you want it autoreleased or not:
/* Not autoreleased */
NSArray *array = [[NSArray alloc] initWithArray:mutableArray];
/* Autoreleased array */
NSArray *array = [NSArray arrayWithArray:mutableArray];
EDIT: The solution provided by Georg Schölly is a better way of doing it and a lot cleaner, especially now that we have ARC and don't even have to call autorelease.
Solution 3
I like both of the 2 main solutions:
NSArray *array = [NSArray arrayWithArray:mutableArray];
Or
NSArray *array = [mutableArray copy];
The primary difference I see in them is how they behave when mutableArray is nil:
NSMutableArray *mutableArray = nil;
NSArray *array = [NSArray arrayWithArray:mutableArray];
// array == @[] (empty array)
NSMutableArray *mutableArray = nil;
NSArray *array = [mutableArray copy];
// array == nil
Solution 4
you try this code---
NSMutableArray *myMutableArray = [myArray mutableCopy];
and
NSArray *myArray = [myMutableArray copy];
Solution 5
Objective-C
Below is way to convert NSMutableArray to 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;
Swift
In Swift 3.0 there is new data type Array. Declare Array using let
keyword then it would become NSArray And if declare using var
keyword then it's become NSMutableArray.
Sample code:
let newArray = oldArray as Array
marcy
Updated on October 11, 2020Comments
-
marcy over 3 years
How do I convert NSMutableArray to NSArray in objective-c?
-
Dan Rosenstark almost 14 yearsthis answer is great, but how can I tell from the docs that
copy
creates a normal NSArray and not an NSMutableArray? -
Vojto over 13 yearsCan I just do (NSArray *) myMutableArray ?
-
hallski over 13 yearsYes, as NSMutableArray is a subclass of NSArray that is valid.
-
sharvey over 13 yearsHowever, casting to (NSArray *) still allows a cast back up to (NSMutable *). Ain't that the case?
-
Stefan over 13 years@sharvey: Yes, that's correct. You'll get a warning if you don't cast but assign a superclass to a subclass directly. Usually, you want to return a immutable copy, because that's the only way to be sure, that your array really won't get modified.
-
Stefan over 13 years@Yar: You look at the documentation of NSCopying It states there: copyWithZone The copy returned is immutable if the consideration “immutable vs. mutable” applies to the receiving object; otherwise the exact nature of the copy is determined by the class.
-
David Snabel-Caunt over 12 yearsVery neat - I prefer this to m5h's solution. Both terse and more efficient.
-
Francisco Gutiérrez about 11 yearsFormerly That's known as "Upcasting" (NSArray *) myMutableArray and the inverse is called "Downcasting"
-
hallski about 11 yearsI agree David, updated my response to point to this response.
-
Bradley Thomas over 9 years@Georg I see lots of up votes for your comment, but frankly I don't have a clue what that Apple doc comment actually means. How does one determine if "the consideration immutable vs mutable applies to the receiving object"?
-
Stefan over 9 years@Brad: That just means classes that have both mutable and immutable implementations. E.g.
NSArray
&NSMutableArray
,NSString
&NSMutableString
. But not for exampleNSViewController
which always contains mutable state. -
Ky - about 8 yearsWhat does this do that the others don't do?
-
durazno almost 8 yearsThis is so wrong. Just checked. [mutableArray copy] also returns an empty array.
-
Richard Venable almost 8 years@durazno It is not wrong. Double check your test. If [mutableArray copy] is returning an empty array, then mutableArray must have been an empty array. My answer only applies when mutableArray is nil.
-
mkirk almost 8 yearsAlthough this is true, I feel like you're missing a more fundamental truth in your example. Since you've assigned mutableArray to be nil,
[mutableArray copy]
can be simplified to[nil copy]
. In objective-c any message sent to nil will always be nil. It's important to remember the distinction between "nothing" and "an array with nothing in it". -
Richard Venable almost 8 years@mkirk Let's not distract from the question at hand: "How do I convert NSMutableArray to NSArray?" There are 2 primary solutions, and the primary difference between them is how they behave when the mutable array is nil.
-
sleighty almost 6 years
-
David Rönnqvist over 5 yearsAssigning an
NSMutableArray
to anNSArray
variable will not covert it (which is what the OP's question is about). Exposing such a value (for example as a return value or as a property) could result in very hard to debug issues if that value was unexpectedly mutated. This applies to both internal and external mutations since the mutable value is shared. -
Anton Tropashko over 5 yearsTo mutate that array you'd have to [NSMutableArray arrayWithArray:... or something like that.
-
David Rönnqvist over 5 yearsNot necessarily. Simply assigning it to a
NSMutableArray
variable is enough. Since the object never stopped being a mutable array, calling mutating methods on it will succeed and mutate the shared data. If on the other hand the original mutable array was copied—changing it to an immutable array—and then assigned to aNSMutableArray
variable and had mutating methods called on it, those calls would fail withdoesNotRespondToSelector
errors because the object that received the mutating method call is in fact immutable and doesn't respond to those methods. -
Anton Tropashko over 5 yearsok, this might have some merit for developers that don't heed the compiler warning about tyope conversion assigments