1

我有这个与更新我的 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];



    });


}];

这是在 viewDidAppear 方法中触发的。

然后我的 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 中的按钮的方法中,我更新了我的 NSMangedObject 的属性:

-(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];

  }

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

4

1 回答 1

1

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

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

因此,您可以尝试的一件事是obtainPermanentIDsForObjects:在将 id 传递给主线程之前调用后台线程中的所有对象。

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

self.dataSourceArray = [_theManagedObjectContext executeFetchRequest:fetchRequest error:&error];
[self.tableView reloadData];

并将此数组用作表视图数据源。在这种情况下,如果您修改对象,reload/insert/deleteRowsAtIndexPaths则必须在必要时调用。

于 2013-04-17T18:54:43.793 回答