0

I have a global NSMutableArray and I need to update it with values. NSMutableArray is defined in the .h as follows;

@property (strong, nonatomic) NSMutableArray *myDetails;

In the viewDidLoad pre-populate like this;

    NSDictionary *row1 = [[NSDictionary alloc] initWithObjectsAndKeys:@"1", @"rowNumber", @"125", @"yards", nil];
    NSDictionary *row2 = [[NSDictionary alloc] initWithObjectsAndKeys:@"2", @"rowNumber", @"325", @"yards", nil];
    NSDictionary *row3 = [[NSDictionary alloc] initWithObjectsAndKeys:@"3", @"rowNumber", @"525", @"yards", nil];
self.myDetails = [[NSMutableArray alloc] initWithObjects:row1, row2, row3, nil];

Then when the user changes a text field this code is run this;

-(void)textFieldDidEndEditing:(UITextField *)textField{
    NSObject *rowData = [self.myDetails objectAtIndex:selectedRow];

    NSString *yards = textField.text;

    [rowData setValue:yards forKey:@"yards"];

    [self.myDetails replaceObjectAtIndex:selectedRow withObject:rowData];
}

When stepping through the code on the line [rowData setValue:yards forKey:@"yards"]; it returns this error;

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'

1 Answer 1

2

The array is mutable, but what is in it... NSDictionary... is not. You grab an object out of the array...

NSObject *rowData = [self.myDetails objectAtIndex:selectedRow];

and then you try to mutate that object...

[rowData setValue:yards forKey:@"yards"];

The object in the array is the thing you are changing... and it is NSDictionary, immutable, and you can not change it. If you want the dictionary to be mutable, you have to use NSMutableDictionary

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

2 Comments

Jody is right, but: you are both attempting to modify the dictionary that's already in the array and also "replacing" the dictionary. I put "replacing" in quotes because you're replacing it with itself. You can either use mutable dictionaries and drop the call to -replaceObjectAtIndex:withObject: or you can continue using immutable dictionaries in the array but build a new dictionary and keep the replacement logic.
Thanks both of you, a simple over sight that I hope not make again!

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.