【问题标题】:Deleting object from one to many relationship in Core Data在Core Data中从一对多关系中删除对象
【发布时间】:2013-06-13 16:21:46
【问题描述】:

我目前在删除一对多关系中的对象时遇到问题。

我的app有如下关系:

产品

当用户在我的视图控制器中按下“添加到购物车”按钮时,以下代码正在设置产品对象和购物车之间的关系

    + (Cart *)addProductToCartWithProduct:(Product *)product inManagedObjectContext:(NSManagedObjectContext *)context {

    Cart *cart = nil;

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Cart"];

    NSError *error = nil;
    NSArray *carts = [context executeFetchRequest:request error:&error];

    if (!carts || ([carts count] > 1)) {
        // handle error
    } else if (![carts count]) {
        cart = [NSEntityDescription insertNewObjectForEntityForName:@"Cart" inManagedObjectContext:context];


    } else { // they already have a cart started
        cart = [carts lastObject];
    }
    /*Get Object ID to safely pass NSMangedObject between threads (A background worker thread and the main thread). */
      NSManagedObjectID *retID = [product objectID];
    [cart addProductsObject:(Product *)[context objectWithID:retID]];

//Inverse relationship
    [(Product *) [context objectWithID:retID] setInCart:cart];


     return cart;
}

然后返回一个购物车对象,我将它传递给我的购物车视图控制器,并像这样获取该关系中的产品:

             // Fetch request for "Product":
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Product"];

// Fetch only products for the cart:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"inCart = %@", self.cart];
[fetchRequest setPredicate:predicate]; 


NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"navn" ascending:YES];
[fetchRequest setSortDescriptors:@[sortDescriptor]];

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

当我尝试像这样从关系中删除一个对象时:

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

     NSIndexPath *ip = [NSIndexPath indexPathForRow:sender.tag inSection:0];

    Product *prod = (Product *)[self.fetchedResultsController objectAtIndexPath:ip];



       prod.inCart = nil;
       [_cart removeProductsObject:prod];


    NSLog(@"Cart %@ %@", _cart.products, prod);


    [self saveCurrentContext:_theManagedObjectContext];




    [self loadCart]; 
    [_orderTable reloadData];


}

产品在视觉上被删除(从表格视图/屏幕中消失),因为 inCart 设置为 nil,但从技术上讲不是......当我记录购物车对象时,产品对象仍在关系中,所以看起来像[_cart removeProductsObject:prod]; 不工作。

而且反过来也行不通,当我尝试将相同的产品添加到购物车时,我刚刚删除了(从购物车中),由于某种原因,未设置反向关系“inCart”,在我将它设置为“nil”之后,当产品对象被删除时。

为什么会这样?我该如何解决? :)。

编辑:

Core 数据模型编辑器中展示逆向关系的图片:

将购物车传递给其他视图控制器:

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


    UITabBarController *tabBarController = self.tabBarController; 

    for (UINavigationController *navController in  tabBarController.viewControllers) {


        for (UIViewController *vc in navController.viewControllers) {
            if ([vc isMemberOfClass:NSClassFromString(@"CartViewController")]){ 
               CartViewController *cartVC = (CartViewController *) vc;
                cartVC.cart = [Cart addProductToCartWithProduct:prod inManagedObjectContext:         [[DataManager sharedInstance] backgroundManagedObjectContext]];

                [[DataManager sharedInstance] saveBackgroundContext];
                [[DataManager sharedInstance] saveMasterContext];

                NSLog(@" %@", cartVC.cart); 
            }
        }

    }



}];

保存上下文

-(void)saveCurrentContext:(NSManagedObjectContext *)context  {

    NSError *error = nil;
    if (![context save:&error]) {
        NSLog(@"NOT SAVED");
    }
    [[DataManager sharedInstance] saveBackgroundContext];
    [[DataManager sharedInstance] saveMasterContext];



}

【问题讨论】:

  • 您确定inCartproducts 在Core Data 模型编辑器中被正确定义为“反向关系”吗?设置(或删除)关系的一侧就足够了,而不是像您在代码中所做的那样。
  • 我很确定它们在我的核心数据模型编辑器中定义正确...我添加了一些屏幕截图(在上面的编辑下),在编辑器中具有反比关系,看起来是否正确? :)
  • 这种关系在我看来还不错。那么为什么你总是设置两个方向的关系呢?
  • 好的,谢谢。嗯,有趣的问题......我认为这已经成为一种习惯,我认为这样做是某种“最佳实践”。但是即使我删除了设置反向关系的代码,它仍然不起作用。我不知道为什么它不起作用..? :) 谢谢你的帮助。
  • 您确定saveCurrentContext 操作没有失败吗? - 除此之外,我目前不知道是什么导致了您的问题。

标签: ios core-data sdk


【解决方案1】:

好的,所以我找到了解决这个非常奇怪的问题的方法。 由于自动生成的访问器方法由于某种原因不起作用,我不得不考虑另一种方法从关系中删除对象。

          for (Product *prod in _cart.products) {

//To Very reliable to check for item by name attribute, but It works :) 
              if ([prod.name isEqualToString:product.name]) {

                        product = prod; 

       NSMutableSet *set = [NSMutableSet setWithSet:_cart.products];
       [set removeObject:prod];
       _cart.products = set;


              }


            }

【讨论】:

  • 我在使用 swift + NSMutableOrderedSet 时遇到了同样的问题。您是否有机会成功完成这项工作?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-31
  • 2011-01-13
  • 1970-01-01
  • 2011-09-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多