Search code examples
iosobjective-cnsmutablearraynsarray

delete element from table view objective c


I have a table view full of data defined from the user. the array is gathered from nsuserdefaults and is show in a table view controller. i am trying to implement a delete function. it looks fine but when i press delete the error comes

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray removeObjectAtIndex:]: mutating method sent to immutable object'

The code i have for Favourites.h

#import <UIKit/UIKit.h>

@interface FavoritesViewController: UITableViewController <UITableViewDelegate, UITableViewDataSource>
@property(nonatomic, strong) IBOutlet UITableView *tableView;
@property (nonatomic,strong) NSMutableArray *favoriteItems;

@end

Then the piece where i initialize

- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];

favoriteItems= [[NSUserDefaults standardUserDefaults] objectForKey:@"favoritesArray"];
[self.tableView reloadData];


}

I feel like the above code is where the problem is. NSUserDefaults; I expect is an NSArray. So how do I change it too Mutable?

Just for interests sake the following sets up the delete method

 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
    //remove the deleted object from your data source.
    //If your data source is an NSMutableArray, do this
    [self.favoriteItems removeObjectAtIndex:indexPath.row];
    [[NSUserDefaults standardUserDefaults] setObject:favoriteItems forKey:@"favoritesArray"];
    [self.tableView reloadData]; // tell table to refresh now
  }
}

Really appreciate the help in advance.


Solution

  • The problem is that [[NSUserDefaults standardUserDefaults] objectForKey:@"favoritesArray"] is returning an NSArray, not an NSMutableArray.

    The solution is to create a mutable copy of the array when you load it from NSUserDefaults:

    [[[NSUserDefaults standardUserDefaults] objectForKey:@"favoritesArray"] mutableCopy];

    This is one of the most confusing aspects of Objective-C's type system. You'd naturally think that if the system lets you assign something to an NSMutableArray variable, then it must be an NSMutableArray (in Swift, you'd be right). But there is absolutely no guarantee of this in ObjC - the syntax makes the language look like it's statically typed, but it isn't.