Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/121.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios CoreData子上下文不';t在保存第二次后将更改推送到父级_Ios_Core Data_Nsmanagedobjectcontext - Fatal编程技术网

Ios CoreData子上下文不';t在保存第二次后将更改推送到父级

Ios CoreData子上下文不';t在保存第二次后将更改推送到父级,ios,core-data,nsmanagedobjectcontext,Ios,Core Data,Nsmanagedobjectcontext,我应该保存配方,如果用户按下喜欢按钮,如果不喜欢应该删除 我有两种情况: 上下文A(父)-persistentContainer.viewContext 上下文B(儿童)- 在RecipeVC上,我有childManagedObjectContext和recipe。我使用它就像沙盒用户可以喜欢/不喜欢很多次 第一次: 当用户喜欢菜谱时。 我保存的是B而不是A。 当用户不喜欢时,我从A按id获取配方并调用delete 但如果用户再次喜欢配方并保存B,则更改不会出现在A上下文中。此时hasChang

我应该保存配方,如果用户按下喜欢按钮,如果不喜欢应该删除

我有两种情况:

上下文A(父)-persistentContainer.viewContext

上下文B(儿童)-

在RecipeVC上,我有childManagedObjectContext和recipe。我使用它就像沙盒用户可以喜欢/不喜欢很多次

第一次: 当用户喜欢菜谱时。 我保存的是B而不是A。 当用户不喜欢时,我从A按id获取配方并调用delete

但如果用户再次喜欢配方并保存B,则更改不会出现在A上下文中。此时
hasChanges
属性的状态为false

链:保存B->保存A->删除A->保存B->(?)配方应出现在A

为什么保存后配方不显示在A中

func changeFavoriteStatus() {
        isFavorite = !isFavorite
        let parantContext = managedObjectContext!.parent!
        if !isFavorite {
            deleteRecipeInTheParentContext()
        } else {
            if managedObjectContext!.hasChanges {
                managedObjectContext?.performAndWait{
                    do {
                        try managedObjectContext?.save()
                    } catch {  print(error) }

                    if parantContext.hasChanges {
                        parantContext.performAndWait{
                            do {
                                try parantContext.save()
                                let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity.name!)
                                let predicate = NSPredicate(format: "id == %i",id)
                                fetchRequest.predicate = predicate

                                do {
                                    let recipes = try parantContext.fetch(fetchRequest) as! [Recipe]
                                    print("\(recipes.count) found")
                                } catch { print(error) }
                            } catch {
                                print(error) } } } } } }
    }

    private func deleteRecipeInTheParentContext() {
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity.name!)
        let predicate = NSPredicate(format: "id == %i",id)
        fetchRequest.predicate = predicate
        let parantContext = managedObjectContext!.parent!

        do {
            let recipes = try parantContext.fetch(fetchRequest) as! [Recipe]

            parantContext.performAndWait {
                for reipe in recipes { parantContext.delete(reipe) }
                do {
                    try parantContext.save()
                } catch { print(error)  }
            }
        } catch { print(error)  }
    }
func changeFavoriteStatus(){
isFavorite=!isFavorite
让parantContext=managedObjectContext!.parent!
如果!我最喜欢{
deleteRecipeInTheParentContext()
}否则{
如果managedObjectContext!.hasChanges{
managedObjectContext?.performAndWait{
做{
请尝试managedObjectContext?.save()
}捕获{打印(错误)}
如果parantContext.hasChanges{
parantContext.performAndWait{
做{
请尝试parantContext.save()
让fetchRequest=NSFetchRequest(entityName:entity.name!)
let谓词=NSPredicate(格式:“id==%i”,id)
fetchRequest.predicate=谓词
做{
let recipes=尝试parantContext.fetch(fetchRequest)as![Recipe]
打印(\(recipes.count)找到)
}捕获{打印(错误)}
}抓住{
打印(错误)}}}}
}
private func deletRecipeInTheParentContext()函数{
让fetchRequest=NSFetchRequest(entityName:entity.name!)
let谓词=NSPredicate(格式:“id==%i”,id)
fetchRequest.predicate=谓词
让parantContext=managedObjectContext!.parent!
做{
let recipes=尝试parantContext.fetch(fetchRequest)as![Recipe]
parantContext.performAndWait{
对于配方中的reipe{parantContext.delete(reipe)}
做{
请尝试parantContext.save()
}捕获{打印(错误)}
}
}捕获{打印(错误)}
}

可能是您遇到了冲突。您是否尝试记录其中任何一个?我不确定(根据您所写的内容),但它看起来像是从上下文A中删除一个项目,然后从上下文B中修改它。如果项目已在上被删除,则需要创建一个新项目,而不是修改现有项目。第二个操作很可能没有效果,因为托管对象有点像僵尸;数据库中的源对象已被删除。@MaticOblak日志中没有任何内容。删除后,我可以打印和查看配方的所有参数和关系。在何处查看?您的上下文在内存中保存从数据库检索到的数据,然后被插回。多个上下文意味着您拥有内存中数据对象的多个实例。其思想是只在内存中保存您当前需要的数据,您可以修改这些数据并将其插入硬盘上的数据库中。所以,当一个上下文保存到数据库中时,它不应该影响第二个上下文。第二个上下文需要从数据库重新加载数据,以查看大多数情况下的更改。因此,您仍然可以看到托管对象中的所有数据。
func changeFavoriteStatus() {
        isFavorite = !isFavorite
        let parantContext = managedObjectContext!.parent!
        if !isFavorite {
            deleteRecipeInTheParentContext()
        } else {
            if managedObjectContext!.hasChanges {
                managedObjectContext?.performAndWait{
                    do {
                        try managedObjectContext?.save()
                    } catch {  print(error) }

                    if parantContext.hasChanges {
                        parantContext.performAndWait{
                            do {
                                try parantContext.save()
                                let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity.name!)
                                let predicate = NSPredicate(format: "id == %i",id)
                                fetchRequest.predicate = predicate

                                do {
                                    let recipes = try parantContext.fetch(fetchRequest) as! [Recipe]
                                    print("\(recipes.count) found")
                                } catch { print(error) }
                            } catch {
                                print(error) } } } } } }
    }

    private func deleteRecipeInTheParentContext() {
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity.name!)
        let predicate = NSPredicate(format: "id == %i",id)
        fetchRequest.predicate = predicate
        let parantContext = managedObjectContext!.parent!

        do {
            let recipes = try parantContext.fetch(fetchRequest) as! [Recipe]

            parantContext.performAndWait {
                for reipe in recipes { parantContext.delete(reipe) }
                do {
                    try parantContext.save()
                } catch { print(error)  }
            }
        } catch { print(error)  }
    }