1

I'm trying to edit an object in NSMutable array declared in .h file and synthesised in .m file, but the app crashes with debug saying: Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray replaceObjectAtIndex:withObject:]: mutating method sent to immutable object'

The line that makes the app crash is:

[noteContent replaceObjectAtIndex:currentNote withObject:noteText.text];

noteContent is declared in .h @property (nonatomic, strong) NSMutableArray* noteContent;, synthesised in .m @synthesize noteContent and initialized in viewDidLoad

noteContent = [[NSMutableArray alloc] init];
noteContent = [standardUserDefaults objectForKey:@"noteContent"];

The problem isn't in replacing nil object, because I checked that at the position, an actual string is stored.

Thank you for your effort.

1 Answer 1

5

You've assigned an NSArray to noteContent:

noteContent = [standardUserDefaults objectForKey:@"noteContent"];

So, while you've declared your variable to be a mutable array, the actual object being referenced is immutable. Try this:

noteContent = [[NSMutableArray alloc] initWithArray:[standardUserDefaults objectForKey:@"noteContent"]];

As @Abizern explains in the comments, there is an argument to be made for doing:

noteContent = [[standardUserDefaults objectForKey:@"noteContent"] mutableCopy];

However, it should be noted that, with this approach, noteContent will be nil if [standardUserDefaults objectForKey:@"noteContent"] returns nil. So, if presumably you're going to be adding items to the mutable array, you would need to add more code to handle the nil case.

Sign up to request clarification or add additional context in comments.

5 Comments

noteContent = [[standardUserDefaults objectForKey:@"noteContent"] mutableCopy]; rather than initWithArray:, surely.
@Abizern You're probably right, but the advantages aren't immediately obvious to me. Perhaps you could expand on "surely"?
Say you have an NSArray object and an NSMutableArray object. sending copy to an NSArray will just return the NSArray object with in incremented reference count, but sending it to an NSMutableArray` object will return a copy of the object, but as an NSArray object. Sending mutableCopy to either will return a mutable version, regardless of whether the receiver is mutable or immutable. I say surely because a) it does the correct thing based on what the actual type of the reciever is and b) It's far more readable (IMHO).
@Abizern Thanks. Seems to be a matter of style for mutableCopy, but your overall argument makes sense and I've added your suggestion to the answer.
@Abizern updated my answer to point out that your approach would generally require additional code to handle the nil case.

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.