我有一个推车控制器。用户可以将项目添加到他的愿望清单中。如果我们没有任何愿望清单,我们应该创建默认列表。这是工作2-3次,如果我添加,然后删除,然后再次添加。然后我得到错误:
非法尝试在对象之间建立关系'wishList' 在不同的背景下
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)")
}
})
}
}
为什么背景会改变?
答案 0 :(得分:1)
您正在尝试在与创建托管对象上下文不同的线程上创建和保存CoreData对象。 UITableViewRowAction的处理程序提供了一个块回调,它将在另一个线程上异步发生。
为了在不同的线程上创建和保存对象,您需要创建另一个NSManagedObjectContext
concurrencyType
PrivateQueueConcurrencyType
,然后使用后台线程中的那个。
所以这就是我如何重写你的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)