0

I was having a problem with my app throwing an exception when calling removeObjectAtIndex on an NSMutableArray, saying that myLocationsArray was declared immutable. All other manipulation on that array was fine, it was most definitely declared correctly etc etc but somewhere in my app it was getting set as immutable. After investigating for a while trying to find where it was getting set immutable, I decided screw it and just redeclared the variable as such:

myLocationsArray = [[NSMutableArray alloc] initWithArray:[defaults
objectForKey:MYLOCATIONSARRAY_KEY]];

right before the removeObjectAtIndex call.

However I know this has got to be badwrong, I'm calling alloc/init twice on the same variable. However it's the only thing that has worked. Is there any way to remind this variable that it is an NSMutableArray without introducing memory leaks like I am?

1
  • 1
    You need to show some code that deals with the array and might cause this, otherwise it's hard for anyone to offer proper advice. Commented Apr 27, 2012 at 16:07

4 Answers 4

1

NSUserDefaults returns immutable copy of your array. It doesn't matter whether you put NSArray or NSMutableArray in it, it always give you immutable copy back.

So, do this to get a mutable copy that you can work with

myLocationsArray = [[NSMutableArray alloc] initWithArray:[[[defaults objectForKey:MYLOCATIONSARRAY_KEY] mutableCopy] autorelease]];

or just this

myLocationsArray = [[defaults objectForKey:MYLOCATIONSARRAY_KEY] mutableCopy];
Sign up to request clarification or add additional context in comments.

1 Comment

I eventually realized the problem was with NSUserDefaults returning immutable NSArrays but I was re-declaring them NSMutableArrays to fix it, didn't realize I could just tell it to give me a mutable copy :-D
1

I would suggest to set a breakpoint on the line where your program is throwing an exception (the one containing removeObjectAtIndex) and inspect with the debugger the real type of the array. If you go with you mouse over the array name, a popup menu will display giving you all the information you need about the pointed object.

What I expect is that you find out this way that the object is an NSArray (vs. NSMutableArray) and then trace back to the point where you initialized it in the first place.

Comments

1

It looks like you're working with NSUserDefaults. All objects you get out of NSUserDefaults are always immutable, regardless of what you stored into it. NSUserDefaults doesn't keep a reference to the specific object you set into it, it keeps the data. It's effectively making a copy. When you get something out of NSUserDefaults, it makes a new (immutable) object from the data it has stored and gives that to you.

Unsurprisingly, you can't change what's stored in NSUserDefaults by mutating what you (think you) stored in it. You can only change what's stored by replacing what you previously stored by storing something anew.

1 Comment

Yep, it turned out to be NSUserDefaults. I made sure to declare my NSMutableArray before assigning the data blob from NSUserDefaults into it and that fixed it and allows mutation at will. Thanks!
0

The declaration should not matter; your error is a run-time error. It sounds like your myLocationsArray variable has been assigned an immutable array (NSArray) though whether it is being re-assigned somewhere or was always immutable is impossible to say from your code fragment.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.