This is my code
NSMutableArray * reversedNamesArray; //theres about a thousand variable already stored in here, this is just for documentation
reversedNamesArray = [reversedNamesArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
//Incompatible pointer type assigning "NSMutableArray" to "NSArray"
The message above is what i get, i know what it means, but i don't want to take an extra step of copying an NSMutableArray of a thousand variable to a NSArray is there any cast i can use to fix the warning, it doesn't affect my code, but i just want a fix for it. and can you explain why they are not compatible, they NSMutableArray and NSArray should use the same amount of bytes so i don't see why they are incompatible in the first place.
-sortedArrayUsingSelector: is implemented in NSArray and returns an NSArray even when called on an NSMutableArray.
You should use one of the sort methods implemented in NSMutableArray. This would work:
[reversedNamesArray sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
@GerdK's answer is the right one, but I thought I would explain why you cannot just cast an NSArray into NSMutableArray. If you could, major optimizations would be lost. Consider the following:
NSArray *first = @[...];
NSArray *second = [first copy];
This is extremely cheap. second just adds an extra retain onto first and we're done. On the other hand:
NSMutableArray *first = [NSMutableArray arrayWith…]
NSArray *second = [first copy];
This is more expensive. In order to create second, we actually have to create new array and copy the pointers over and add extra retains.
Now, imagine what you're requesting were legal:
// Not legal, but let's say it were
NSArray *first = @[...];
NSMutableArray *second = (NSMutableArray *)[first copy];
Now [NSArray copy] has to be defensive against this. It has to implement copy as a full (expensive) copy. That's a real performance loss.
You might say "But I'll just use copy when I want to really copy and retain when I want to retain." Sure, but that's not good enough. Say I want to store an immutable copy of something I'm passed:
- (void)setSomething:(NSArray *)array {
_something = [array copy];
}
This is a very efficient and correct setter. If I pass a real NSArray, then it's cheap (and this is probably the normal case). If I pass an NSMutableArray (it's a subclass, so I can do that), then I automatically make a real copy (so the object can't change behind my back). You get this kind of optimization for free by keeping mutable and immutable objects separate. Otherwise, I'd have to interrogate the object and ask if it were mutable and then make decisions based on that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With