Objective c 更新对象时,UITableview中的核心数据对象将消失

Objective c 更新对象时,UITableview中的核心数据对象将消失,objective-c,core-data,nsfetchedresultscontroller,Objective C,Core Data,Nsfetchedresultscontroller,我有一个与更新NSManagedObject相关的奇怪问题。当我尝试更新中的某个属性时,它将在显示它的UITableview中消失,并且仅在我从核心数据重新提取时再次消失。我认为这是由于我如何在另一个线程中获取实体的内容造成的,如下所示: [[[DataManager sharedInstance] backgroundManagedObjectContext] performBlock:^{ NSFetchRequest *fetchRequest = [[NSFetchReques

我有一个与更新NSManagedObject相关的奇怪问题。当我尝试更新中的某个属性时,它将在显示它的UITableview中消失,并且仅在我从核心数据重新提取时再次消失。我认为这是由于我如何在另一个线程中获取实体的内容造成的,如下所示:

[[[DataManager sharedInstance] backgroundManagedObjectContext] performBlock:^{

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    fetchRequest.entity = [NSEntityDescription entityForName:@"Ret" inManagedObjectContext:[[DataManager sharedInstance] backgroundManagedObjectContext]];

    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"menu.name == %@ ", self.menu.name];

    fetchRequest.resultType = NSManagedObjectIDResultType;

    NSArray *results =  [[[DataManager sharedInstance] backgroundManagedObjectContext] executeFetchRequest:fetchRequest error:nil];




    NSLog(@"%@", [NSThread currentThread]);
    dispatch_async(dispatch_get_main_queue(), ^{


        [self loadWithObjectIDs:results];
        [_theTableview reloadData];



    });


}];
这是在ViewDidAspect方法中激发的

然后使用我的NSFetchResultsController方法更新主线程上的UI:

-(void)loadWithObjectIDs:(NSArray *)objectsIDs {





    _theManagedObjectContext = [[DataManager sharedInstance] mainManagedObjectContext];



    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    fetchRequest.entity = [NSEntityDescription entityForName:@"Ret" inManagedObjectContext:_theManagedObjectContext];


   fetchRequest.predicate = [NSPredicate predicateWithFormat:@"SELF IN %@ ", objectsIDs];


    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    fetchRequest.sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

    [NSFetchedResultsController deleteCacheWithName:@"dishes"];
    self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:_theManagedObjectContext sectionNameKeyPath:nil cacheName:@"dishes"];
    _fetchedResultsController.delegate = self;


    NSError *error = nil;   


    if (![_fetchedResultsController performFetch:&error]) {
        NSLog(@"Fetch Failed");

    }


    NSArray *contentsOfFetch = _fetchedResultsController.fetchedObjects;



}
然后,在另一个连接到UITableViewCell中按钮的方法中,我更新NSMangeObject的属性:

-(void)addTC:(UIButton *)sender {

   //sender.tag equals indexPath.row
   NSIndexPath *ip = [NSIndexPath indexPathForRow:sender.tag inSection:0];



    Ret *ret = (Ret*)[_fetchedResultsController objectAtIndexPath:ip];

   //The Cell disappears if I use this code to update my attribute. 

   NSInteger amountToUpdate = ret.amount.intValue;
    amountToUpdate++;
    ret.amount = [NSNumber numberWithInt:amount];

    /*Method to Save Main Context: includes:  
    NSError *error = nil;
    if (![context save:&error]) {

    }*/

    [self saveCurrentContext:_theManagedObjectContext];

  }

在我的UITableview中,当我更新NSManagedObject的属性时,如何解决这个小问题,使其不会消失

我看不出使用获取结果控制器(FRC)作为表视图有什么好处 设置中的数据源。FRC对于自动更新变更的变更跟踪非常有用 表视图。但这在这里并不适用,因为实际的获取是在后台完成的 线程和获取的对象(通过对象id)传递给主线程

如果托管对象id是临时id,也可能存在问题。如果保存该对象,则id会更改(成为永久id)。这可以解释为什么这个物体是 从表视图中消失

因此,您可以尝试调用中所有对象的
getainpermanentidsforobjects:
将ID传递给主线程之前的后台线程

或者,您可以只执行一个简单的获取

self.dataSourceArray = [_theManagedObjectContext executeFetchRequest:fetchRequest error:&error];
[self.tableView reloadData];
并将此数组用作表视图数据源。在这种情况下,如果修改对象,则
如有必要,必须调用
重新加载/插入/删除rowsatindexpaths

我认为使用获取结果控制器(FRC)作为表视图没有任何好处 设置中的数据源。FRC对于自动更新变更的变更跟踪非常有用 表视图。但这在这里并不适用,因为实际的获取是在后台完成的 线程和获取的对象(通过对象id)传递给主线程

如果托管对象id是临时id,也可能存在问题。如果保存该对象,则id会更改(成为永久id)。这可以解释为什么这个物体是 从表视图中消失

因此,您可以尝试调用中所有对象的
getainpermanentidsforobjects:
将ID传递给主线程之前的后台线程

或者,您可以只执行一个简单的获取

self.dataSourceArray = [_theManagedObjectContext executeFetchRequest:fetchRequest error:&error];
[self.tableView reloadData];
并将此数组用作表视图数据源。在这种情况下,如果修改对象,则
如果需要,必须调用
reload/insert/deleteRowsAtIndexPaths

为什么在这里使用“获取结果”控制器?一个简单的获取请求就足够了吗?我使用NSFetchResultsController填充UITableview,这不是正确的方法吗?如果我错了,请更正:)如果要跟踪更改(插入、删除、更改的对象)并自动更新表视图,NSFetchResultsController通常很有用。否则,您可以使用
executeFetchRequest
获取一个数组,并将其用作表视图的数据源。-第一次抓取是在后台线程上进行的,这是否很耗时?如果主抓取是在后台线程上进行的,那么我认为使用抓取结果控制器作为表视图数据源没有任何好处。啊,好的。我需要有机会更新获取的NSManagedObjects的属性,否则我不需要UITableView自动更新和跟踪更改。如果我选择使用NSArray作为数据源,是否仍有可能更新获取对象的属性。。。我在后台线程上执行抓取的原因是出于“安全原因”,并且在抓取时不会阻止主UI,因为我不知道从JSON提要接收多少数据。既然我还没有为IOS编程的丰富经验,为什么在这里使用“获取结果”控制器?一个简单的获取请求就足够了吗?我使用NSFetchResultsController填充UITableview,这不是正确的方法吗?如果我错了,请更正:)如果要跟踪更改(插入、删除、更改的对象)并自动更新表视图,NSFetchResultsController通常很有用。否则,您可以使用
executeFetchRequest
获取一个数组,并将其用作表视图的数据源。-第一次抓取是在后台线程上进行的,这是否很耗时?如果主抓取是在后台线程上进行的,那么我认为使用抓取结果控制器作为表视图数据源没有任何好处。啊,好的。我需要有机会更新获取的NSManagedObjects的属性,否则我不需要UITableView自动更新和跟踪更改。如果我选择使用NSArray作为数据源,是否仍有可能更新获取对象的属性。。。我在后台线程上执行抓取的原因是出于“安全原因”,并且在抓取时不会阻止主UI,因为我不知道从JSON提要接收多少数据。由于我还没有为IOS编程的丰富经验,再次感谢您。我还有一个关于内存使用和使用数组填充tableview的问题。如果我有1000多个需要在tableview中显示的对象,那么使用数组作为数据源是否有效?@Seya:你是对的,这可能是个问题。您是否尝试了第一个建议(获取对象的永久性)?-我还建议您尝试直接在主线程上获取(使用FRC)并检查是否存在真正的性能问题。是的,在获取对象后,我确实尝试在我的后台线程中使用“获取永久对象”,但出于某种原因,我的ap