核心数据:我应该从父上下文中获取对象还是子上下文是否具有与父上下文相同的对象?

2024-03-05

我对父母/孩子的背景有点困惑ManagedObjectContext.

当我设置子上下文并设置父上下文时,子上下文是否包含父上下文的所有对象?我正在使用库存Core Data在中创建的方法AppDelegate,但我改变了ConcurrencyQueue到主要。

在我的方法中应该更新数据库:

  • 创建子上下文,设置父上下文
  • 对子上下文执行阻止
  • 从父上下文中获取
  • 在子上下文中创建或更新对象
  • 在子上下文中调用保存
  • 有通知侦听器来处理子上下文保存
  • 保存父上下文

我的问题是,看起来我没有将任何内容保存到子上下文中。我没有收到 Update 或 Create ChatMessage 的 println 消息。我在这里做错了什么?

AppDelegate 核心数据方法

lazy var managedObjectContext: NSManagedObjectContext? = {
        // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
        let coordinator = self.persistentStoreCoordinator
        if coordinator == nil {
            return nil
        }

        var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
        managedObjectContext.persistentStoreCoordinator = coordinator
        managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy

        NSNotificationCenter.defaultCenter().addObserver(self, selector: "contextDidSave:", name: NSManagedObjectContextDidSaveNotification, object: nil)

        return managedObjectContext
    }()

    func contextDidSave(notification: NSNotification) {
        let sender = notification.object as! NSManagedObjectContext
        if sender != managedObjectContext {
            managedObjectContext?.mergeChangesFromContextDidSaveNotification(notification)
            println("Core Data: merging changes from child context")
            saveContext()
        }
    }

处理更新的数据库类

lazy var parentContext: NSManagedObjectContext? = {
        if let managedObjectContext = self.appDelegate.managedObjectContext {
            return managedObjectContext
        }
        else {
            return nil
        }
        }()

func updateMessage(chatMessage: ChatMessage) {
        if chatMessage.id.isEmpty { return }

        let childContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
        childContext.parentContext = parentContext
        childContext.performBlock({
            let objectIdDesc = NSExpressionDescription()
            objectIdDesc.name = "objectID"
            objectIdDesc.expression = NSExpression.expressionForEvaluatedObject()
            objectIdDesc.expressionResultType = NSAttributeType.ObjectIDAttributeType

            let fetchRequest = NSFetchRequest(entityName: "ChatMessage")
            fetchRequest.predicate = NSPredicate(format: "id == %@", chatMessage.id)
            fetchRequest.propertiesToFetch = [objectIdDesc]
            fetchRequest.resultType = .DictionaryResultType

            var error: NSError?
            if let results = self.parentContext!.executeFetchRequest(fetchRequest, error: &error) {
                if error == nil {
                    if !results.isEmpty {
                        if let objectId = results[0].valueForKey("objectID") as? NSManagedObjectID {
                            let fetched = childContext.objectWithID(objectId) as! ChatMessage
                            fetched.id = chatMessage.id
                            fetched.senderUserId = chatMessage.senderUserId
                            fetched.senderUsername = chatMessage.senderUsername
                            fetched.receiverUserId = chatMessage.receiverUserId
                            fetched.receiverUsername = chatMessage.receiverUsername
                            fetched.messageType = chatMessage.messageType
                            fetched.message = chatMessage.message
                            fetched.timestamp = chatMessage.timestamp
                            fetched.filepath = chatMessage.filepath
                            println("Updated ChatMessage: \(fetched.id)")
                        }
                        else {
                            var newMessage = NSEntityDescription.insertNewObjectForEntityForName("ChatMessage", inManagedObjectContext: childContext) as! ChatMessage
                            newMessage.id = chatMessage.id
                            newMessage.senderUserId = chatMessage.senderUserId
                            newMessage.senderUsername = chatMessage.senderUsername
                            newMessage.receiverUserId = chatMessage.receiverUserId
                            newMessage.receiverUsername = chatMessage.receiverUsername
                            newMessage.messageType = chatMessage.messageType
                            newMessage.message = chatMessage.message
                            newMessage.timestamp = chatMessage.timestamp
                            newMessage.filepath = chatMessage.filepath
                            println("Create ChatMessage: \(newMessage.id)")
                        }
                    }
                }
                else {
                    println("Fetch Message Object ID Error: \(error?.localizedDescription)")
                }
            }
        })
        childContext.save(nil)
    }

创建子上下文然后从父上下文中获取似乎没有太大意义。我不认为这是子上下文块的使用方式。

为了消除混乱:从父上下文创建子上下文后,该子上下文具有与父上下文相同的“状态”。只有当两个上下文执行不同的操作(创建、修改、删除对象)时,两个上下文的内容才会有所不同。

因此,对于您的设置,请按以下步骤操作:

  • 创建子上下文
  • 做您想做的工作(从下载的数据修改或创建对象),
  • 保存子上下文

在此阶段,尚未将任何内容保存到持久存储中。通过子保存,更改只是“推送”到父上下文。你现在可以

  • 保存父上下文

将新数据写入持久存储。然后

  • 更新你的用户界面,

最好通过通知(例如NSManagedObjectContextDidSaveNotification).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

核心数据:我应该从父上下文中获取对象还是子上下文是否具有与父上下文相同的对象? 的相关文章

  • 从 IOS 应用程序注销的完美方法是什么?

    下面的代码可以工作 但有一个错误 场景是 我首先登录进入应用程序系统 登录成功后 应用程序将设置 UserDefaults UserId 之后 我可以使用存储的 UserId 导航应用程序视图 一旦我进入设置和选项卡注销 这将清除 User
  • iOS 上的 OpenCV - VideoCapture 属性始终返回 1

    我一直在尝试构建一个简单的 OpenCV iOS 应用程序 该应用程序从捆绑包中加载视频并查询其帧数 持续时间等 然后它将尝试从中获取各个帧 不幸的是 当我使用VideoCapture类中 所有属性返回值 1 然后我尝试导航到frame 1
  • 如何在 swiftUI (macOS) 中检测按键按下和释放

    除了标题之外没什么可说的 我希望能够在按下按键和释放按键时 在 macOS 上 在 swiftUI 视图中执行操作 在 swiftUI 中是否有任何好的方法可以做到这一点 如果没有 有什么解决方法吗 不幸的是 键盘事件处理是其中一个令人痛苦
  • 从 NavigationController 中删除 ViewController 后 AVPlayer 继续播放

    因此 我在项目中使用 ARC 当我添加 AVPlayerLayer 时 它工作得很好 但当我从 UINavigationItem 中弹出 UIViewController 时 视频继续在后台播放 有谁知道你会如何处理这个问题 这似乎是一件很
  • 使 iOS 应用程序与 iPhone 6 和 iPhone 6 尺寸兼容 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我创建了一个应用程序 其中使用 xib 进行布局 目前我使用两种不同的 xib 一种用于iPhone4 320 480 一种用于iPh
  • 删除派生数据文件夹后,Xcode 不断重新创建派生数据文件夹

    自动完成功能在 Xcode 6 中不再起作用 我四处搜索 发现删除派生数据文件夹可以解决此问题 每次我删除它时 它都会回来 然后就不会再自动完成了 有什么建议么 Thanks 没关系 我解决了这个问题 我没有声明需要在类内的方法中使用的变量
  • 为 Swift 对象/属性设置观察者

    我一直在寻找一种在连接到 Mac 的显示器数量发生变化时触发方法的方法 我知道我可以获得 NSScreen screens count 的值 但我需要找到一种方法来在该值发生变化时创建通知或其他内容 或者指示所连接的显示器数量发生变化的其他
  • 将自定义图像设置为 UIBarButtonItem 但它不显示任何图像

    我想将自定义图像设置为 UIBarButtonItem 但它只显示周围的矩形框并且不显示实际图像 func setupBrowserToolbar let browser UIToolbar frame CGRect x 0 y 20 wi
  • iOS UITableViewCell cell.imageView 设置圆角

    嘿我正在尝试设置cell imageView s cornerRadius 但似乎不起作用 cell imageView layer cornerRadius 9 它会起作用还是我应该添加自定义UIImageView在我的牢房里有圆角吗 我
  • 通过 renderInContext 定位要绘制的视图:

    我想画一个UIView在我目前的CGGraphicsContext 我画的是UIView via renderInContext 但它的位置不正确 始终位于左上角 我拥有所有的价值观UIView可用于绘制UIView CGRect fram
  • Swift 3 中的 JSON 解析

    有没有人能够找到一种在 Swift 3 中解析 JSON 文件的方法 我已经能够返回数据 但在将数据分解为特定字段时我没有成功 我会发布示例代码 但我已经尝试了很多不同的方法但没有成功 并且没有保存任何代码 我想要解析的基本格式是这样的 提
  • 为 iOS 应用程序加载基于 SVG 的图像资源

    我从 thenounproject 购买了一个图标作为 SVG 图像 然后我使用一个名为的 macOS 程序Gapplin http gapplin wolfrosch com 将此 SVG 导出为 PNG 图像 它显示为 100x100
  • 从 Mac 命令行访问 iOS 应用程序目录(沙箱)

    我需要使用 Mac 或 Linux 上的命令行 非 GUI 访问 iOS 设备上安装的应用程序的沙箱目录 这有助于开发和测试自动化 将 json 文件放入沙箱中可以让我设置参数 例如额外的调试消息和更小的刷新间隔 像 iFunBox 这样的
  • 查找已用应用程序名称的捆绑包/开发人员

    我正在尝试将应用程序上传到应用程序商店并收到以下错误 很容易理解 The App Name you have entered has already been used 该应用程序不在 iTunes 上 有什么方法可以找出谁拥有该应用程序或
  • 沙盒尝试恢复消耗性 IAP

    我一直在尝试在 iOS 上测试一些消耗性 IAP 但遇到了一个奇怪的错误 弹出一条警报 其中包含以下文本 此应用内购买已被购买 它将恢复为 自由的 环境 沙盒 我已经检查过 并且确定我的 IAP 可以在 iTunesConnect 中使用
  • 如何使用 Core Graphics 在我的触摸位置绘制一个圆圈?

    新程序员来了 我在尝试使用 Core Graphics 在触摸位置周围绘制描边弧时遇到问题 我有绘制圆圈的方法工作正常 并且我已经测试并在点击屏幕时注册触摸 但是当我尝试在点击时调用绘制圆圈的方法时 我收到错误 CG ContextBlah
  • iOS 防止计时器 UILabel 在数字变化时“晃动”

    我有一个UILabel它以以下格式显示计时器的输出MM ss SS 分 秒 厘秒 但是随着厘秒宽度的变化 它从左向右 摇动 例如 11 比 33 窄 有什么办法可以减轻这种情况吗 我尝试过将其居中 给它固定的宽度 但它们似乎没有帮助 从iO
  • NSCFData fastCharacterContents 崩溃? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我目前在控制台中收到此崩溃日志 20
  • ios 导航 堆栈操作

    我在尝试从 iOS 应用程序操作导航堆栈时遇到问题 或者至少是由于这种操纵而产生的行为 我的情况 我有 3 个 ViewController 控制器a显示多个级别 控制器 b 是游戏视图 控制器 c 是某种分数 显然 我将在控制器 a 中选
  • DatePicker 停止 CoreData 按预期工作

    我有一个应用程序 它保存 UIDatePicker 中的文本和日期 然后在您回到 UIDatePicker 中的该日期时显示该注释 效果很好 只有我发现将 UIDatePicker 日期设置为今天会停止 CoreData 工作 只有当我运行

随机推荐