Reputation: 1820
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
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
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