同时可靠地使用核心数据

2024-03-13

我正在构建我的第一个 iOS 应用程序,理论上它应该非常简单,但我很难让它足够安全,让我有信心将其提交到 App Store。

简而言之,主屏幕有一个表视图,在选择一行后,它会转到另一个表视图,该表视图以主从方式显示与所选行相关的信息。底层数据每天从 Web 服务中以 JSON 数据形式检索一次,然后缓存在核心数据存储中。当天之前的数据将被删除,以阻止 SQLite 数据库文件无限增长。所有数据持久化操作均使用 Core Data 执行,NSFetchedResultsController支持详细信息表视图。

我看到的问题是,如果在检索、解析和保存新数据的同时在主屏幕和详细屏幕之间快速切换几次,应用程序将完全冻结或崩溃。似乎存在某种竞争条件,可能是由于核心数据在后台导入数据而主线程尝试执行获取,但我猜测。我很难捕获任何有意义的崩溃信息,通常是核心数据堆栈深处的 SIGSEGV。

下表显示了加载详细信息表视图控制器时发生的实际事件顺序:



Main Thread                          Background Thread
viewDidLoad

                                     Get JSON data (using AFNetworking)

Create child NSManagedObjectContext (MOC)

                                     Parse JSON data
                                     Insert managed objects in child MOC
                                     Save child MOC
                                     Post import completion notification

Receive import completion notification
Save parent MOC
Perform fetch and reload table view

                                     Delete old managed objects in child MOC
                                     Save child MOC
                                     Post deletion completion notification

Receive deletion completion notification
Save parent MOC
  

一旦 JSON 数据到达时触发 AFNetworking 完成块,就会出现一个嵌套的NSManagedObjectContext创建并传递给“导入器”对象,该对象解析 JSON 数据并将对象保存到核心数据存储中。导入器使用新的执行performBlockiOS 5中引入的方法:

NSManagedObjectContext *child = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [child setParentContext:self.managedObjectContext];        
    [child performBlock:^{
        // Create importer instance, passing it the child MOC...
    }];

导入器对象观察它自己的 MOCNSManagedObjectContextDidSaveNotification然后发布自己的通知,该通知由详细表视图控制器观察到。当发布此通知时,表视图控制器在其自己的(父)MOC 上执行保存。

我使用与“删除器”对象相同的基本模式来在导入当天的新数据后删除旧数据。在获取结果控制器获取新数据并且重新加载详细信息表视图之后,这会异步发生。

我没有做的一件事是观察任何合并通知或锁定任何托管对象上下文或持久存储协调器。这是我应该做的事情吗?我有点不确定如何正确地构建这一切,因此将不胜感激任何建议。


在 iOS 5 之前,我们通常有两个NSManagedObjectContexts:一个用于主线程,一个用于后台线程。后台线程可以加载或删除数据然后保存。所结果的NSManagedObjectContextDidSaveNotification然后被传递(正如您所做的那样)到主线程。我们打电话mergeChangesFromManagedObjectContextDidSaveNotification:将它们带入主线程上下文。这对我们来说效果很好。

其中一个重要的方面是save:在后台线程上blocks直到之后mergeChangesFromManagedObjectContextDidSaveNotification:完成在主线程上的运行(因为我们从监听器调用 mergeChanges... 到该通知)。这可确保主线程管理的对象上下文看到这些更改。我不知道你是否need如果您有亲子关系,则可以这样做,但您在旧模式中这样做以避免各种麻烦。

我不确定在两个上下文之间建立父子关系有什么好处。从您的描述看来,最终保存到磁盘发生在主线程上,出于性能原因这可能并不理想。 (特别是如果您可能要删除大量数据;我们应用程序中删除的主要成本始终发生在最终保存到磁盘期间。)

当控制器出现/消失时,您正在运行哪些代码可能导致核心数据出现问题?您在哪种类型的堆栈跟踪上看到崩溃?

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

同时可靠地使用核心数据 的相关文章

  • 适用于 IOS 和 Android 的支付网关 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在开发一个应用程序 用户必须在澳大利亚餐馆通过应用程序 android ios 付款 有两种付款方式 通过 PayPal 或 Visa
  • 从命令行调试 iOS 应用程序构建

    我正在通过命令行构建 iOS 应用程序 但在调试它时遇到问题 如果我使用 XCode 进行构建 它会让我在设备上 构建和调试 而不会出现任何问题 但现在 我不知道如何使用 gdb 在设备上启动它并逐步执行它 如果我尝试 添加自定义目标 可执
  • Objective-c 中的块递归

    当执行涉及 Objective C 块的递归时 我在 iOS 应用程序中收到 EXC BAD ACCESS 信号 这是简化的代码 void problematicMethod FriendInfo friendInfo onComplete
  • 当 UITextField 已满或空时显示警报 Swift

    下面的代码中 如果 userNameTF 或 passwordTF 已满或为空 则会显示警报 IBAction func LoginBtn sender AnyObject let userName userNameTF text let
  • 自定义 UITableViewCell 选择样式?

    当我点击我的UITableViewCell 当我单击单元格时 背景部分 我的背景图像未覆盖的区域 会变成蓝色 另外 所有的UILabel单击时单元格上的 s 变为白色 这就是我想要的 然而 我不想要的是当我点击它时的蓝色背景 但如果我这样做
  • iPhone UINavigationBar 使用 [UINavigationBar 外观] 更改所有控制器的字体样式

    我知道我可以单独更改导航栏的字体 如本答案所述 更改导航栏的字体 https stackoverflow com questions 5832036 change the navigation bars font 目前我正在使用一种更全局的
  • 在iOS上,“添加到主页”缓存保存在哪里,如何清除它?

    我正在 iPad iOS v7 上制作一个 html5 游戏 当我将其添加到主页时 它非常顽固地释放缓存 如果我在 Safari 中查看它 这会按照您所期望的方式工作 如果我刷新一次或两次 页面就会以最新状态缓存 但在主页上却是另一回事 它
  • 现有的和未输入错误的密钥的 NSUnknownKeyException

    我得到以下输出 Terminating app due to uncaught exception NSUnknownKeyException reason
  • UIScrollView - 启用分页后,我可以“更改”页面宽度吗?

    将滚动视图 将 pagingEnabled 设置为 YES 将页面宽度设置为滚动视图边界以外的其他值的最简单方法是什么 让我举个例子 假设我有一个包含 10 个项目的滚动视图 每个项目的宽度为 150 像素 而我的滚动视图的宽度为 300
  • iphone NSDate 转换问题

    在我的 facebook 图表 Api 中 我正在获取这些数据 来自杰森 updated time 2011 05 17T14 52 16 0000 我正在使用此代码将其转换为有效的日期格式 NSDateFormatter df NSDat
  • Xcode 中的 iOS 9 警告 - 此文件设置为针对早于项目部署的版本进行构建。功能可能有限

    我刚刚将我的 Mac 更新到最新的操作系统 并将 Xcode 更新到最新版本 现在我收到此警告 但我不知道该由谁来删除它 也不知道它的真正含义是什么 有人可以向我解释一下吗 Thanks Select Main storyboard in
  • 使用 MFMailComposeViewController 类从 iPhone 应用程序发送带有 IMG 标签的 HTML 电子邮件

    我正在使用 MFMailComposeViewController 类从我的 iPhone 应用程序发送格式化的 HTML 电子邮件 我需要在电子邮件中包含图像 并且我在电子邮件正文中添加了 IMG 标签 IBAction shareWit
  • 防止 AlertView 被解雇

    任何人都可以帮助我防止在其按钮单击事件上解雇警报视图吗 我有一个 textview 作为我的alertView 的子视图 如果 textview 值为 nil 我不想关闭它 因为这是一个非常老的问题 但我得到了一个解决方案 并且如果其他开发
  • 来自 iPhone/iPad 的 json Web 服务

    有人可以帮助我解决如何从 iphone 或 ipad 使用 json Web 服务的问题吗 这里我的要求是使用 API 密钥实现 json webservice 如果可能的话发布一些教程或示例链接 谢谢 规范的 JSON 处理库是here
  • iphone:如何停止快门动画?

    我有两个问题 1 我想知道如何在相机加载时停止快门动画 我正在使用 UIImagePickerController 我已经参考了堆栈溢出的许多答案 但没有成功 2 我在相机中有一个自定义按钮 使用cameraOverlayView并想通过单
  • Google 地图 API -> OpenGLES 崩溃

    日志是从 Crashlytics 粘贴的 对于许多用户来说 崩溃经常发生 据我所知 它与设备 iOS 版本无关 我在我的代码中找不到任何错误 这似乎是纯粹的库问题 是 Google 地图 API 错误吗 我可以做些什么来修复它 或者我应该在
  • 指定访问组时出现 KeychainItemWrapper 错误

    相当长一段时间以来 我一直在使用 KeychainItemWrapper 的 ARC 版本成功读取和写入私有钥匙串项目 我现在正在努力将我的 iOS 应用程序转换为使用共享访问组 以便我的 2 个共享相同应用程序前缀的应用程序可以访问钥匙串
  • git 提交错误:检测到大文件

    您好 我正在为 ios 8 1 开发一个应用程序 xcode 我已经使用 googleMaps 框架来实现自动完成功能 当我尝试在 Git 中推送我的项目时 我收到大文件检测错误 后来尝试使用 git lfs 并跟踪 git 检测到的文件
  • IPV6 快速可达性

    我是 swift 和 xcode 的新手 并且我的应用程序因 IPV6 而被拒绝 性能 2 1 当我们执行以下操作时 您的应用程序会在运行 iOS 9 3 5 并连接到 IPv6 网络的 iPad 和 iPhone 上崩溃 具体来说 当我们
  • CGImage/UIImage 在 UI 线程上延迟加载会导致卡顿

    我的程序显示一个水平滚动表面 从左到右平铺有 UIImageViews 代码在 UI 线程上运行 以确保新可见的 UIImageView 分配有新加载的 UIImage 加载发生在后台线程上 一切工作几乎都很好 除了每个图像变得可见时出现口

随机推荐