我无法重现的用户可能会导致 CoreData 崩溃

Posted

技术标签:

【中文标题】我无法重现的用户可能会导致 CoreData 崩溃【英文标题】:Possible CoreData crashing from users I can't reproduce 【发布时间】:2018-05-03 19:59:21 【问题描述】:

我的应用程序连接了 Crashlytics,大约 9% 的用户(接近 1k)遇到了我无法复制的崩溃。在崩溃的特定行中,我将托管对象上下文传递给使用它来查找数据的函数。

使用依赖注入,我能够使用在我的 AppDelegate 中创建的托管对象上下文来实例化我的主视图控制器。任何需要托管对象上下文的类都会从这个主视图控制器中注入它。下面是我在 Crashlytics 仪表板中获得的堆栈跟踪。任何帮助都可以帮助我弄清楚我能做什么。

崩溃:com.apple.main-thread 0 MyApp 0x10008f47c 专门 CalendarService.parseCalendarForMeetings(来自:[EKEvent]?)-> [会议]? (CalendarService.swift:96) 1 MyApp 0x10006dbf4 专门的 MeetingViewController.(launchCalendarService() -> ()).(closure #1) (MeetingViewController.swift:188) 2 MyApp 0x100071e64 部分申请 MeetingViewController.(launchCalendarService() -> ()).(closure #1) (MeetingViewController.swift) 3 MyApp 0x1000a5950 thunk (MeetingListMenuViewController.swift) 4 libdispatch.dylib 0x1806fabb8 _dispatch_block_async_invoke_and_release + 100 5 libdispatch.dylib 0x1806ee9a0 _dispatch_client_callout + 16 6 libdispatch.dylib 0x1806f35e8 _dispatch_main_queue_callback_4CF + 996 7 核心基础 0x1817e50c8 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12 8 核心基础 0x1817e2ce4 __CFRunLoopRun + 1572 9 核心基础 0x181712da4 CFRunLoopRunSpecific + 424 10 图形服务 0x18317d074 GSEventRunModal + 100 11 UIKit 0x1879cdc9c UIApplicationMain + 208 12 MyApp 0x10005b3cc 主 (AppDelegate.swift:27) 13 libdyld.dylib 0x18072159c 开始 + 4

编辑:

这似乎是问题所在的代码行(每个堆栈跟踪的第 96 行)。 MOC 在 CalendarService 类和 CalendarUtility 类中不是可选的。

在 CalendarUtility 中,MOC 仅用于读取数据。

let calendarUtil = CalendarUtility(title: event.title, location: event.location, notes: event.notes, managedObjectContext: managedObjectContext)

【问题讨论】:

添加堆栈跟踪顶部引用的代码并告诉我们 CalendarService.swift 中的第 96 行是什么 既然您知道文件和行号,接下来您要做的就是查看该代码,看看那里或导致它的代码中可能出现的问题。如果您不确定,请使用该信息更新您的问题。基于此,任何人都可以真正说的是应用程序在 CalendarService.swift:96 处崩溃,它是从 MeetingViewController.swift:188 调用的。 更新了导致崩溃的代码行 【参考方案1】:

您可能遇到了争用情况,并且受影响的用户往往拥有更快或更慢的设备,这暴露了问题。

您可以参考以下SO post,其中讨论了添加调试设置以检查 CoreData 正在使用的线程。如果操作发生在后台线程上,那么您很可能会崩溃。

【讨论】:

我添加了这个,我看到核心数据违规崩溃。以前从不知道这个调试标志,所以感谢你让我朝着正确的方向前进! @ioshepherd 很高兴听到这个消息,CoreData 有时可能是一个雷区,但这是驯服它的重要资产。 所以我尝试使用 persistentContainer.newBackgroundContext() 修复代码并遇到崩溃,所以我切换回旧代码并检查,这次我没有崩溃......所以我的生产代码不包含任何违规行为:/

以上是关于我无法重现的用户可能会导致 CoreData 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

使用 CoreData 获取时崩溃

仅在 iPhone 5C 上滚动 UITableView 会导致异常和崩溃

CoreData insertNewObjectForEntityForName 导致崩溃

无法重现的 webcore 崩溃

将 HttpClient 设置为太短的超时会导致进程崩溃

CoreData 同步 iCloud 数据导致 App 启动超时被系统 watchdog 终止的原因及解决