简体   繁体   中英

iOS UITableView with core data crash after delete

I'm working on an iOS app written in Objective-C and I have table view with many records from Core data. When I delete one record the row is deleted from Core data but the app is giving me an error:

-[_PFArray removeObjectAtIndex:]: unrecognized selector sent to instance 0x7fbf5be5e6b0

I have tried many times to change this but it still crashes the app or the table view is not updated after deletion.

This is my header file:

#import <UIKit/UIKit.h>
#include "Notes.h"
@interface ShowClassNote : UIViewController<UITabBarDelegate,UITableViewDataSource>

// get moodle id from segue
@property(strong,nonatomic)NSString*moodeleID;
@property(strong,nonatomic)NSString*moodleName;
@property(strong,nonatomic)NSString*content;
@property (nonatomic, strong) NSMutableArray *fetchedObjects;

@property(strong)NSManagedObjectContext*passThis;

@property(strong,nonatomic)NSString*dataForSend;
@property(strong,nonatomic)NSArray*noteID;
@property(strong,nonatomic)NSArray*noteTitle;
@property(strong,nonatomic)NSArray*insertDates;
@property(strong,nonatomic)NSArray*noteContent;

@property (weak, nonatomic) IBOutlet UILabel *classTitleLable;

@property (weak, nonatomic) IBOutlet UITableView *allNotes;

@end

and this is my implementation file:

#import "ShowClassNote.h"
#import "Subjects.h"
#import "NewClassNote.h"
#import "Notes.h"
#import "AllClassNotesCell.h"
@interface ShowClassNote ()

@end

@implementation ShowClassNote

- (void)viewDidLoad {
    [super viewDidLoad];

    id delegate =[[UIApplication sharedApplication]delegate];

    NSError*error=nil;

    NSManagedObjectContext *context = [delegate managedObjectContext];



    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Notes"
                                              inManagedObjectContext:context];
   NSPredicate * predicate =[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"moodleCode=='%@'",self.moodeleID]];
    [fetchRequest setPredicate:predicate];
    [fetchRequest setEntity:entity];
    self.fetchedObjects = [[NSMutableArray alloc]initWithObjects:[context executeFetchRequest:fetchRequest error:&error], nil];
   // self.fetchedObjects =(NSMutableArray *) [context executeFetchRequest:fetchRequest error:&error];

   // NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
    self.noteTitle  =[[[NSArray alloc]initWithArray:_fetchedObjects]valueForKey:@"title"];
    self.insertDates  =[[[NSArray alloc]initWithArray:_fetchedObjects]valueForKey:@"insertDate"];
    self.noteContent  =[[[NSArray alloc]initWithArray:_fetchedObjects]valueForKey:@"content"];
    self.noteID=[[[NSArray alloc]initWithArray:_fetchedObjects]valueForKey:@"moodleCode"];

    self.classTitleLable.text=self.moodleName;

    self.title=self.moodleName;

    [self.allNotes reloadData];


}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{

    return 0;

}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    // This will create a "invisible" footer
    return 0.01f;
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    // Return the number of rows in the section.
    return [self.fetchedObjects count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {


    static NSString * cellIdnt =@"noteCell";

    AllClassNotesCell *cell =(AllClassNotesCell *) [tableView dequeueReusableCellWithIdentifier:cellIdnt forIndexPath:indexPath];

    // Configure the cell...
    // Get current date & time
    NSDate *currDate =  [self.insertDates objectAtIndex:indexPath.row];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
    [dateFormatter setDateFormat:@"dd/MM/YY HH:mm"];
    NSString* dateToString =[dateFormatter stringFromDate:currDate];




    cell.textLabel.text= [self.noteTitle objectAtIndex:indexPath.row]  ;
     cell.detailTextLabel.text=dateToString;

    return cell;
}


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 78;
}



-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{




        id delegate =[[UIApplication sharedApplication]delegate];

        // Delete the role object that was swiped
        NSUInteger currentSelect = indexPath.row;


        NSManagedObjectContext *context = [delegate managedObjectContext];



        Notes * roleToDelete= [self.fetchedObjects objectAtIndex:currentSelect];
        [context deleteObject:roleToDelete];

        // Save the context.
        NSError *error;

        if (![context save:&error])
        {

            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        }


    [_fetchedObjects removeObjectAtIndex:currentSelect];
    [self.allNotes reloadData];





}


-(void)viewWillAppear:(BOOL)animated{
    id delegate =[[UIApplication sharedApplication]delegate];

    NSError*error=nil;

    NSManagedObjectContext *context = [delegate managedObjectContext];



    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Notes"
                                              inManagedObjectContext:context];
    NSPredicate * predicate =[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"moodleCode=='%@'",self.moodeleID]];
    [fetchRequest setPredicate:predicate];
    [fetchRequest setEntity:entity];

     self.fetchedObjects = (NSMutableArray *)[context executeFetchRequest:fetchRequest error:&error];
    self.noteTitle  =[[[NSArray alloc]initWithArray:_fetchedObjects]valueForKey:@"title"];
    self.insertDates  =[[[NSArray alloc]initWithArray:_fetchedObjects]valueForKey:@"insertDate"];

    self.classTitleLable.text=self.moodleName;

    self.title=self.moodleName;

    [self.allNotes reloadData];

}



#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {


    if ([[segue identifier]isEqual:@"newNote"]) {

        NewClassNote * newNoteView =[segue destinationViewController];
        newNoteView.moodleID =self.moodeleID;
        newNoteView.newOrOld =YES;
    }else if ([[segue identifier]isEqual:@"showNote"])
    {

        NewClassNote * dvc =[segue destinationViewController];
        NSUInteger currentSelect = [self.allNotes indexPathForSelectedRow].row;
           NSLog(@"Send is %lu",(unsigned long)currentSelect);
        dvc.returnData =[self.fetchedObjects objectAtIndex:currentSelect];



        NewClassNote *destViewController = segue.destinationViewController;

        destViewController.comingData = [self.noteTitle objectAtIndex:[[self.allNotes indexPathForSelectedRow] row]];
        destViewController.insertDate=  [self.insertDates objectAtIndex:[[self.allNotes indexPathForSelectedRow] row]];

        [self.allNotes reloadData];
    }
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}



@end

Can you explain to me why I get this error? The total rows after deletion is different than before deletion but I don't know why this errors?

You error goes from here:

self.fetchedObjects = (NSMutableArray *)[context executeFetchRequest:fetchRequest error:&error];

-executeFetchRequest:error: returns NSArray, it's immutable, if you just cast it to NSMutableArray it won't magically change itself. But later you try to

[_fetchedObjects removeObjectAtIndex:currentSelect];

which is sending -removeObjectAtIndex to an NSArray instance.

You can try to solve it like this:

self.fetchedObjects = [[context executeFetchRequest:fetchRequest error:&error] mutableCopy];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM