2015-11-11 2 views
0

У меня есть контроллер тележки. Пользователь может добавить элемент в свой список пожеланий. Если у нас нет списка желаний, мы должны создать по умолчанию. Это работает 2-3 раза, если я добавляю, а затем удаляю, а затем добавляю снова. И тогда я получаю ошибку:Почему различные разные контексты в одном представлении?

Illegal attempt to establish a relationship 'wishList' between objects in different contexts

class CartViewController: UIViewController, NSFetchedResultsControllerDelegate { 
     var fetchResultController:NSFetchedResultsController! 
     var shopItems:[ShopItem] = [] 
     let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate 

     override func viewDidLoad() { 
      self.fetchResultController = NSFetchedResultsController(fetchRequest: fetchRequest, 
        managedObjectContext: self.appDelegate.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil) 
      self.fetchResultController.delegate = self 
      do { 
       try fetchResultController.performFetch() 
       self.shopItems = fetchResultController.fetchedObjects as! [ShopItem] 
      } catch { 
       fatalError("Failure to save context: \(error)") 
      } 

     } 
     func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? { 

      let addToWishListAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Add to wish list", handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in 
       var wishListResults:[WishList] = [] 
       let fetchRequest = NSFetchRequest(entityName: "WishList") 
       var wishList:WishList 
       fetchRequest.fetchLimit = 1 

       //...some other code 

       wishList = NSEntityDescription.insertNewObjectForEntityForName("WishList", inManagedObjectContext: self.appDelegate.managedObjectContext) as! WishList 
       wishList.setValue("Default wish list", forKey: "title") 
       wishList.setValue("My wish list", forKey: "desc") 

       let shopItem = self.fetchResultController.objectAtIndexPath(indexPath) as! ShopItem 

       shopItem.setValue(true, forKey: "inWishList") 
       shopItem.setValue(wishList, forKey: "WishList") 

       do { 
        try self.appDelegate.managedObjectContext.save() 
       } catch { 
        fatalError("Failure to save context: \(error)") 
       } 
      }) 
     } 
    } 

Почему контекст изменился?

ответ

1

Вы пытаетесь создать и сохранить объекты CoreData в другом потоке, чем был создан контекст управляемого объекта. Обработчик для UITableViewRowAction обеспечивает обратный вызов блока, который будет выполняться асинхронно в другом потоке.

Для того, чтобы создавать и сохранять объекты в различном потоке, вам нужно создать еще один NSManagedObjectContext из concurrencyTypePrivateQueueConcurrencyType, а затем использовать его из фоновой темы.

Так вот как бы я заново написать свой метод editActionsForRowAtIndexPath (потому что каждый хочет, чтобы скопировать и вставить, верно?):

func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? { 

    let privateMOC = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType) 
    privateMOC.parentContext = self.appDelegate.managedContext 
    let addToWishListAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Add to wish list", handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in 
     var wishListResults:[WishList] = [] 
     let fetchRequest = NSFetchRequest(entityName: "WishList") 
     var wishList:WishList 
     fetchRequest.fetchLimit = 1 

     //...some other code 

     wishList = NSEntityDescription.insertNewObjectForEntityForName("WishList", inManagedObjectContext: privateMOC) as! WishList 
     wishList.setValue("Default wish list", forKey: "title") 
     wishList.setValue("My wish list", forKey: "desc") 

     let shopItem = self.fetchResultController.objectAtIndexPath(indexPath) as! ShopItem 

     shopItem.setValue(true, forKey: "inWishList") 
     shopItem.setValue(wishList, forKey: "WishList") 

     do { 
      try privateMOC.save() 
     } catch { 
      fatalError("Failure to save context: \(error)") 
     } 
    }) 
} 

Кроме того, убедитесь, что вы создаете ManagedObjectContext использовать MainQueueConcurrencyType как:

var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) 
+0

> Кроме того, убедитесь, что вы создаете ManagedObjectContext использовать MainQueueConcurrencyType как: вы имеете в виду заменить это:. '' 'пусть AppDelegate = UIApplication.sharedApplication() вычеркивать ворота как! AppDelegate''' ?? Потому что я использую это в каждом контроллере? это нормально ? – Arti

+0

теперь я получаю ошибку '' 'Незаконная попытка установить связь''' каждый раз. Это не помогает – Arti

+0

Этот ответ фактически не затрагивает проблему потока, и реальная проблема заключается в том, что вы смешиваете объекты в двух контекстах – Wain

Смежные вопросы