mnort9
mnort9

Reputation: 1820

Passing immutable array to mutable property

In my prepareForSegue method, I pass an immutable array retrieved from NSUserDefaults to a DetailViewController mutable dictionary property. Do I need to create a mutable copy of the array before I modify it or does that happen automatically in the NSMutableDictionary class setter method?

My code...

ViewController.m

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"EditReminder"])
    {
        UINavigationController *navigationController = segue.destinationViewController;
        DetailViewController *detailViewController = [[navigationController viewControllers] objectAtIndex:0];
        detailViewController.delegate = self;
        [detailViewController setTitle:@"Edit Reminder"];
        // Pass ReminderData to detailVC if editing
        NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
        NSArray *remindersArray = [[NSUserDefaults standardUserDefaults] objectForKey:@"reminders"];
        detailViewController.reminderData = [remindersArray objectAtIndex: selectedRowIndex.row];
    }
}

DetailViewController.h

@property (strong, nonatomic) NSMutableDictionary *reminderData;

DetailViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];

    if (self.reminderData) {
        // Reminder data from user defaults is immutable. Create mutable copy.
        // Is this necessary?
        self.reminderData = [self.reminderData mutableCopy];
    }
    else {
        self.reminderData = [[NSMutableDictionary alloc] init];
    }
}

Upvotes: 0

Views: 304

Answers (2)

warrenm
warrenm

Reputation: 31782

Yes, you definitely need to create a mutable copy as you've illustrated here. The compiler might not complain if you assign an instance of NSDictionary (immutable) to an NSMutableDictionary-valued property, but calling any of the mutating methods on the stored object will cause a runtime exception. There's no magic in the language or framework that makes an immutable collection assigned to a mutable-typed variable automatically mutable.

Also, as noted in another answer, you should perform the mutable copy when you assign the property for the first time (in prepareForSegue), rather than at a later time.

Upvotes: 1

Eiko
Eiko

Reputation: 25632

You need to create the mutable copy, but your implementation is wrong.

In prepareForSegue, you need to do the mutableCopy, or you already have a wrong object stored in your property. There is no reason to do that in viewDidLoad, and it can be considered a bug.

Upvotes: 1

Related Questions