为啥在一个视图中有不同的上下文?
Posted
技术标签:
【中文标题】为啥在一个视图中有不同的上下文?【英文标题】:Why different different contexts in one view?为什么在一个视图中有不同的上下文? 【发布时间】:2015-11-11 21:55:59 【问题描述】:我有一个购物车控制器。用户可以将项目添加到他的愿望清单中。如果我们没有任何愿望清单,我们应该创建默认清单。这是工作 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)")
)
为什么上下文改变了?
【问题讨论】:
【参考方案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)
【讨论】:
> 另外,请确保您正在创建 ManagedObjectContext 以使用 MainQueueConcurrencyType 作为:您的意思是替换它:let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
??因为我在每个控制器中都使用它?这正常吗?
现在我每次都收到错误Illegal attempt to establish a relationship
。没有帮助
这个答案实际上并没有解决线程问题,真正的问题是您在 2 个上下文中混合对象以上是关于为啥在一个视图中有不同的上下文?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我们将视图和上下文对象作为函数中的参数传递,API 22 [关闭]
为啥我会得到:非法尝试在不同上下文中的对象之间建立关系...
为啥在 XAML 中绑定 MainWindow 数据上下文与使用 this.datacontext=this 在代码隐藏中绑定的行为不同?