Question

I thought what I am trying to do is really basic stuffs, I have 2 NSMutableArrays that contains MyItem objects. I want to remove the item from one array and add it to another array but it throws exception when trying to remove it and Yes to save you a complain, my understanding of fundamental OOP is a failure. I am not even dealing with enumerate thru array at all.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{ 
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    MyItem *item = [self.completedItems objectAtIndex:indexPath.row]; 

    if(![self.toDoItems containsObject: item])
        [self.toDoItems addObject: item];

    if([self.completedItems containsObject: item])
        [self.completedItems removeObject:item];

    [self.tableView reloadData]; //reload contents on table view controller
}

Here is the exception

[__NSArrayI removeObject:]: unrecognized selector sent to instance 0x8d8bba0

here is how the arrays are loaded. it is array of dictionaries basically.

@interface ToDoListTableViewController : UITableViewController
    @property (strong) NSMutableArray *completedItems;
    @property (strong) NSMutableArray *toDoItems;  
@end

self.toDoItems = [[NSMutableArray alloc] init]; //initialize array
self.completedItems = [[NSMutableArray alloc] init]; //initialize array

 MyItem *newItem = [[MyItem alloc] init];
            newItem.text = [item valueForKey:@"text"];
            newItem.completed = [[item valueForKey:@"completed"] boolValue];
            newItem.date = [item valueForKey:@"date"];

            if (newItem.completed) {
                [self.completedItems addObject: newItem];
            }
            else
            {
                [self.toDoItems addObject: newItem];
            }

EDIT Maybe this code somehow makes the destination arrays to become Immutable ones?

UINavigationController *navigationController = segue.destinationViewController;
CompleteTableViewController *objChild = (CompleteTableViewController *)navigationController.topViewController;

if(objChild != nil){
     objChild.completedItems =  [self.completedItems copy];
     objChild.toDoItems =  [self.toDoItems copy];
}

Thanks in advance for point out my issue.

Was it helpful?

Solution 2

Based on the code you were reassigning the data to your property as an immutable object

if(objChild != nil){
 objChild.completedItems =  [self.completedItems copy];
 objChild.toDoItems =  [self.toDoItems copy];
}

if you want it to be mutable, you should use:

if(objChild != nil){
 objChild.completedItems =  [self.completedItems mutableCopy];
 objChild.toDoItems =  [self.toDoItems mutableCopy];
}

OTHER TIPS

As the exception points out self.completedItems is an NSArray, not an NSMutableArray. NSArray has no such method removeObject.

Update! There's the problem code!

if(objChild != nil){
     objChild.completedItems =  [self.completedItems copy]; //should be mutableCopy
     objChild.toDoItems =  [self.toDoItems copy]; //should be mutableCopy
}

that is why you get exception:

if (objChild != nil) {
    // INCORRECT immutable copy, aka NSArray
    objChild.completedItems =  [self.completedItems copy]; 
    objChild.toDoItems =  [self.toDoItems copy];
}

the code above should look like:

if (objChild != nil) {
    // CORRECT mutable copy, aka NSMutableArray
    objChild.completedItems =  [self.completedItems mutableCopy];
    objChild.toDoItems =  [self.toDoItems mutableCopy];
}

because it happens in runtime the compiler is not able to warn you, therefore you got the crash only.

__NSArrayI removeObject:]: unrecognized selector sent to instance 0x8d8bba0 , this tells you that your array is not mutable ArrayI (array immutable), please double-check what you have loaded into property. Nothing stops you from loading NSNumber,NSString,NSArray to be loaded into property where you expect type of NSMutableArray, so then you are ready for a nasty surprise...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top