現在、対多関係でオブジェクトを削除する際に問題があります。
私のアプリには次の関係があります。
商品 <<- カート
ユーザーがビューコントローラーで「カートに追加」ボタンを押すと、次のコードは製品オブジェクトとカートの間の関係を設定しています
+ (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」に設定します。
なぜこうなった?どうすれば修正できますか?:)。
編集:
コア データ モデル エディターで逆の関係を示す画像:
Cart を他のビューコントローラーに渡します。
[[[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];
}