7

I'm writing an application to show some news from a portal. The news are fetched using a JSON file from the Internet and then stored into a NSMutableArray using the CoreData Model. Obviously a user can't delete the news from the JSON file on the Internet, but he can hide them locally. The problems come out here, where I have the following code:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {    
if (editingStyle == UITableViewCellEditingStyleDelete) {
    if( !moc ){
        moc = [[NewsFetcher sharedInstance] managedObjectContext];
    }
    [[dataSet objectAtIndex:indexPath.row] setEliminata:[NSNumber numberWithBool:YES]];
    NSError *error;
    if( ![moc save:&error] ){
        NSLog( @"C'è stato un errore!" );
    }
    [dataSet removeObjectAtIndex:indexPath.row];
    [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
}   

The line:

[dataSet removeObjectAtIndex:indexPath.row];

cause my apps to crash with the following error:

2010-07-12 19:08:16.021 ProvaVideo[284:207] * -[_PFArray removeObjectAtIndex:]: unrecognized selector sent to instance 0x451c820 2010-07-12 19:08:16.022 ProvaVideo[284:207] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[_PFArray removeObjectAtIndex:]: unrecognized selector sent to instance 0x451c820'

I'm trying to understand why it doesn't work but I can't. If I re-launch the app, the new is correctly logically cancelled. Any suggestions?? Thanks in advance.


Interface:

@interface ListOfVideo : UITableViewController <NSFetchedResultsControllerDelegate> { 
    NSMutableArray *dataSet;
} 
@property (nonatomic, retain) NSMutableArray *dataSet;

// In the .m file:
@synthesize dataSet;

Initialization in viewDidLoad:

dataSet = (NSMutableArray *) [[NewsFetcher sharedInstance] 
                                fetchManagedObjectsForEntity:@"News" 
                                withPredicate:predicate
                                withDescriptor:@"Titolo"]; 
[dataSet retain]; 

updateDatabase ... this is when checking for new news from the net, I add them in the MutableArray:

[dataSet addObject:theNews];
Georg Fritzsche
  • 97,545
  • 26
  • 194
  • 236
IssamTP
  • 2,408
  • 1
  • 25
  • 48
  • 1
    Are you sure that dataset is a NSMutableArray? If it isn't responding to removeObjectAtIndex: it might just be a NSArray. – Tom H Jul 12 '10 at 17:47
  • 1
    It isn't a `NSMutableArray` if it doesn't respond to that selector. You might not create it correctly or mistakenly use a [`copy` property](http://stackoverflow.com/questions/3220120/nsmutablearray-addobject-nsarrayi-addobject-unrecognized-selector-sent-to/3220137#3220137). If you have doubts try testing for it using `-isKindOfClass:`. – Georg Fritzsche Jul 12 '10 at 17:57
  • umble, it is not a NSMutableArray, but: @interface ListOfVideo : UITableViewController { NSMutableArray *dataSet; } @property (nonatomic, retain) NSMutableArray *dataSet; ... // In the .m file @synthesize dataSet; – IssamTP Jul 12 '10 at 19:44
  • But how do you initialize it `dataSet`? – Georg Fritzsche Jul 12 '10 at 20:42
  • // viewDidLoad dataSet = (NSMutableArray *) [[NewsFetcher sharedInstance] fetchManagedObjectsForEntity:@"News" withPredicate:predicate withDescriptor:@"Titolo"]; [dataSet retain]; // updateDatabase ... this is when checking for new news from the net, I add them in the MutableArray. [dataSet addObject:theNews]; – IssamTP Jul 12 '10 at 22:22
  • Please update your question next time, code in comments is hard to read. – Georg Fritzsche Jul 12 '10 at 22:55
  • I'm sorry man, I'm new here :) Thank you anyway! – IssamTP Jul 13 '10 at 09:24

3 Answers3

24

Your NewsFetcher returns you an immutable array, not a mutable instance. Use the following instead for initialization:

NSArray *results = [[NewsFetcher sharedInstance] 
                     fetchManagedObjectsForEntity:@"News" 
                     withPredicate:predicate
                     withDescriptor:@"Titolo"];
dataSet = [results mutableCopy];

An expression like A *a = (A*)b; only casts the pointer to a different type - it doesn't convert/change the actual type of the instance it points to.

Georg Fritzsche
  • 97,545
  • 26
  • 194
  • 236
5

Verify that dataSet is an NSMutableArray. The exception is getting thrown because it doesn't respond to removeObjectAtIndex.

jdot
  • 801
  • 1
  • 6
  • 9
  • Mumble, it is not a NSMutableArray, but: @interface ListOfVideo : UITableViewController { NSMutableArray *dataSet; } @property (nonatomic, retain) NSMutableArray *dataSet; ... // In the .m file @synthesize dataSet; – IssamTP Jul 12 '10 at 19:42
  • 2
    The property being for a mutable array doesn't make the array magically become mutable. – Joshua Weinberg Jul 12 '10 at 21:33
  • @Joshua, while it doesn't "magically" make it mutable, it will prevent a mutable array from being mutated it it isn't properly defined. – BlackHatSamurai May 18 '13 at 22:51
1

jdot is correct dataSet must be NSMutableArray..

you must do it this way..

  dataSet = [NSMutableArray arrayWithArray:[[NewsFetcher sharedInstance] 
                               fetchManagedObjectsForEntity:@"News" 
                               withPredicate:predicate
                               withDescriptor:@"Titolo"]]; 

Now the dataSet is a mutable instance of the array you got from NewsFetcher and it won't crash on removing objects.

Pankaj Wadhwa
  • 3,073
  • 3
  • 28
  • 37