在删除coredata中的对象后,按照通知重新加载tableview显示奇怪的结果

我是新来的这个coredata。 只是为了熟悉关系,我创build了两个实体CategoryList(由属性'categories'组成)和ExpenseList(由属性'rangespent'组成),它们具有多种关系。 从'CategoryList'到'ExpenseList'的关系是'expenseselist'。 第一个tableview显示每个类别的总费用

food -150 transportation -100 mobile -100 shopping -500 

而第二个tableview显示的是个人开支

 food -100 food -50 transportation -100 mobile -50 mobile -50 shopping -200 shopping -100 shopping -200 

我已经写了代码,从我的第二个tableview中删除一个单独的费用行使用对象ID,因为它的线程安全。 当我从我的第二个表格视图删除食物条目说

 food -50 

当我回到第一个tableview时,它应该更新食物和显示

 food -100 

我已经注册了第一个默认通知中心的tableview,第一个表视图发送通知(通过nslog检查)每当一个对象被删除。 当第一个tableview接收到一个通知它重新加载tableview中的数据。 但是,当重新加载tableview显示的对象被从下一个tableview中删除的类别意想不到的价值。 这两个tableviews通过导航控制器连接。

这是我的第一个tableview的m.file。

 #import "displayTable.h" #import "CategoryList.h" #import "ExpenseList.h" #import "IncomeList.h" #import "coreAppDelegate.h" @interface displayTable () @end @implementation displayTable - (NSManagedObjectContext *)managedObjectContext { NSManagedObjectContext *context = nil; id delegate = [[UIApplication sharedApplication] delegate]; if ([delegate performSelector:@selector(managedObjectContext)]) { context = [delegate managedObjectContext]; } return context; } - (id)initWithStyle:(UITableViewStyle)style { self = [super initWithStyle:style]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; todaysL = [[todayslist alloc]init]; self.expenseArray = [[NSMutableArray alloc] initWithObjects:@"0.00", @"0.00", @"0.00", @"0.00", @"0.00", @"0.00", nil]; self.categoryArray = [[NSMutableArray alloc] initWithObjects:@"food", @"transportation", @"fuel", @"mobile", @"shopping", @"others", nil]; [self populateExpenses]; NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextObjectsDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification) { NSLog(@"Notification received!"); [self populateExpenses]; // [self viewDidLoad]; [self.tableView reloadData]; }]; // Uncomment the following line to preserve selection between presentations. // self.clearsSelectionOnViewWillAppear = NO; // Uncomment the following line to display an Edit button in the navigation bar for this view controller. // self.navigationItem.rightBarButtonItem = self.editButtonItem; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } #pragma mark-Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { //#warning Potentially incomplete method implementation. // Return the number of sections. return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { //#warning Incomplete method implementation. // Return the number of rows in the section. return [self.categoryArray count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; // Configure the cell... if(cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; } cell.textLabel.text = [_categoryArray objectAtIndex:indexPath.row]; cell.detailTextLabel.text = [_expenseArray objectAtIndex:indexPath.row]; return cell; } 

这是我获取数据的函数

 -(void)populateExpenses { NSManagedObjectContext *managedObjectContexts = [self managedObjectContext]; NSEntityDescription *categorylistEntity = [NSEntityDescription entityForName:@"CategoryList" inManagedObjectContext:managedObjectContext]; NSFetchRequest *request = [[NSFetchRequest alloc]init]; [request setEntity:categorylistEntity]; NSError *error =nil; NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:request error:&error]; if(fetchedObjects == nil) { NSLog(@"your fetching cause error"); } else { for(CategoryList *categoryL in fetchedObjects) { if([categoryL.categories isEqualToString: @"food"] ) { for(ExpenseList *expenseL in categoryL.expenselist) { food = food + expenseL.amountSpent; //NSLog(@"display food %f",food); } NSString *foodString = [NSString stringWithFormat:@"%.2f",food]; [self.expenseArray replaceObjectAtIndex:0 withObject:foodString]; //NSLog(@"foooood%f",food); } else if ([categoryL.categories isEqualToString: @"transportation"]) { for(ExpenseList *expenseL in categoryL.expenselist) { transportation = transportation + expenseL.amountSpent; } NSString *transportationString = [NSString stringWithFormat:@"%.2f",transportation]; [self.expenseArray replaceObjectAtIndex:1 withObject:transportationString]; } else if ([categoryL.categories isEqualToString: @"fuel"]) { for(ExpenseList *expenseL in categoryL.expenselist) { fuel = fuel + expenseL.amountSpent; } NSString *fuelString = [NSString stringWithFormat:@"%.2f",fuel]; [self.expenseArray replaceObjectAtIndex:2 withObject:fuelString]; } else if([categoryL.categories isEqualToString: @"mobile"]) { for(ExpenseList *expenseL in categoryL.expenselist) { mobile = mobile + expenseL.amountSpent; } NSString *mobileString = [NSString stringWithFormat:@"%.2f",mobile]; [self.expenseArray replaceObjectAtIndex:3 withObject:mobileString]; } else if([categoryL.categories isEqualToString: @"shopping"]) { for(ExpenseList *expenseL in categoryL.expenselist) { shopping = shopping + expenseL.amountSpent; } NSString *shoppingString = [NSString stringWithFormat:@"%.2f",shopping]; [self.expenseArray replaceObjectAtIndex:4 withObject:shoppingString]; } else if ([categoryL.categories isEqualToString:@"others"]) for(ExpenseList *expenseL in categoryL.expenselist) { others = others + expenseL.amountSpent; } NSString *othersString = [NSString stringWithFormat:@"%.2f",others]; [self.expenseArray replaceObjectAtIndex:5 withObject:othersString]; NSLog(@"%@",othersString); } //NSLog(@"count %d", self.expenseArray.count); } } /* // Override to support conditional editing of the table view. - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { // Return NO if you do not want the specified item to be editable. return YES; } */ /* // Override to support editing the table view. - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { // Delete the row from the data source [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; } else if (editingStyle == UITableViewCellEditingStyleInsert) { // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view } } */ /* // Override to support rearranging the table view. - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { } */ /* // Override to support conditional rearranging of the table view. - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { // Return NO if you do not want the item to be re-orderable. return YES; } */ #pragma mark - Table view delegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // Navigation logic may go here. Create and push another view controller. /* <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil]; // ... // Pass the selected object to the new view controller. [self.navigationController pushViewController:detailViewController animated:YES]; */ } @end 

但是当我退出并重新启动我的应用程序时,所有更新,因为它应该是,但不删除后立即更新。 我不明白为什么。 我也不知道这是否是正确的做法与coredata的方式。 如果有人能指导我,请提前致谢

是的,你错过了核心数据的一些核心概念,这意味着你正在做的工作比你需要的多得多。

您有数据库中顶级类别的名称,但是您不知道按照什么顺序进入,所以您创build一个单独的数组,然后执行一些复杂的工作以从数据库中获取值以相同的顺序。 更好的方法是在数据库中添加一个“displayOrder”字段,然后在字段中添加一个order to the fetch。

完全摆脱你的categoryArray属性,并在你的populateExpenses函数,只要执行提取(使用sorting子句)。 将fetchedObjects保存到数组属性。

你需要做一个抓取来获得你的顶级对象,但是一旦你拥有了它们,你很less需要做更多的抓取。

在你的cellForRowAtIndexPath中:

CategoryList * category = [_fetchedObjects objecatAtIndex:indexPath.row]; cell.textLabel.text = category.categories; cell.detailTextLabel.text = [[category valueForKeyPath:@“expenseselist。@ sum.amountSpent”] description];

您不需要预取,您可以在显示数据时进行此操作。

更新对象以确保您的更改被注意到: –

 for ( NSManagedObject* object in self.categoryArray) { [self.managedObjectContext refreshObject: object mergeChanges:YES]; } 

这在大多数情况下会告诉对象下一次请求时需要重新更新它的值。

希望这可以帮助。

我把它存储在数组后,只清除浮点型variables值就解决了。 因为我之前没有清理浮点variables,而在重新加载表视图时,浮点variables中的以前的值也会再次被添加,从而给出不希望的值。 所以在viewWillAppear方法我写了重新加载表视图和清除浮动variables的内容,它的工作。