使用CoreData获取时发生崩溃

问题描述:

我的应用程序正在生产中,并且在尝试将festRequest的第一个元素转换为某个实体时,Crashlytics发生了一些崩溃。无论我多努力尝试,我都无法重新创建这个崩溃。使用CoreData获取时发生崩溃

static func getSettings() -> NotificationSettingsMO { 
    var settings: NotificationSettingsMO! 

    let moc = DataController.shared.managedObjectContext 

    moc.performAndWait { 
    do { 
     let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "NotificationSettings") 
     settings = try moc.fetch(fetchRequest).first as! NotificationSettingsMO 
    } catch { 
    print(error) 
    } 
    } 

    return settings 

的崩溃发生时试图投请求NotificationSettingsMO的第一个元素,我敢肯定的实体存在,因为我创造它是创建用户时。这也只发生在一小部分用户,但因为它使应用程序崩溃,我想尝试找出是什么原因造成的。

编辑:我已经把它贴崩溃日志

Crashed: com.apple.main-thread 
0 MyApp      0x100073360 specialized static NotificationSettingsMO.(getSettings() -> NotificationSettingsMO).(closure #1) (NotificationSettingsMO.swift:25) 
1 MyApp      0x10007309c partial apply for static NotificationSettingsMO.(getSettings() -> NotificationSettingsMO).(closure #1) (NotificationSettingsMO.swift) 
2 CoreData      0x18311d08c developerSubmittedBlockToNSManagedObjectContextPerform + 196 
3 CoreData      0x18311cf54 -[NSManagedObjectContext performBlockAndWait:] + 220 
4 MyApp      0x100072fa8 specialized static NotificationSettingsMO.getSettings() -> NotificationSettingsMO (NotificationSettingsMO.swift) 
5 MyApp      0x1000d6190 AppDelegate.getDataOnLaunch() ->() (AppDelegate.swift) 
6 MyApp      0x1000da4bc specialized AppDelegate.application(UIApplication, didFinishLaunchingWithOptions : [UIApplicationLaunchOptionsKey : Any]?) -> Bool (AppDelegate.swift:99) 
7 MyApp      0x1000d3eb8 @objc AppDelegate.application(UIApplication, didFinishLaunchingWithOptions : [UIApplicationLaunchOptionsKey : Any]?) -> Bool (AppDelegate.swift) 
8 UIKit       0x1863f29c0 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 400 
9 UIKit       0x186622184 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 2904 
10 UIKit       0x1866265f0 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1684 
11 UIKit       0x186623764 -[UIApplication workspaceDidEndTransaction:] + 168 
12 FrontBoardServices    0x182bbf7ac __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 36 
13 FrontBoardServices    0x182bbf618 -[FBSSerialQueue _performNext] + 168 
14 FrontBoardServices    0x182bbf9c8 -[FBSSerialQueue _performNextFromRunLoopSource] + 56 
15 CoreFoundation     0x1811d509c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24 
16 CoreFoundation     0x1811d4b30 __CFRunLoopDoSources0 + 540 
17 CoreFoundation     0x1811d2830 __CFRunLoopRun + 724 
18 CoreFoundation     0x1810fcc50 CFRunLoopRunSpecific + 384 
19 UIKit       0x1863eb94c -[UIApplication _run] + 460 
20 UIKit       0x1863e6088 UIApplicationMain + 204 
21 MyApp      0x10001ee18 main (Measurement+Network.swift:26) 
22 libdispatch.dylib    0x180c9a8b8 (Missing) 
+0

你可以发布崩溃日志吗?堆栈跟踪一定会有助于确定究竟发生了什么。 –

+0

考虑如果您的获取请求返回0结果会发生什么。 – Jonah

+0

“我已经在Crashlytics上发生了几次崩溃” 您可以附上崩溃报告吗? –

对象不存在,因此崩溃。我个人很恨HATE强制铸造。可选项的全部要点是帮助您管理什么时候什么是零。将as!放入代码中会要求程序崩溃。我建议删除它并用if let替换它。如果你100%肯定它永远不会是零,那么你仍然应该使用if let,并在其他报告崩溃服务,它发生了(使用CrashlyticsrecordError - 它会显示随着你的崩溃)。

至于你的语句:

我敢肯定,实体存在,因为我创造它时创建的用户

说穿了 - 你错了。电脑总是正确的,人类总是错误的。

以下是可能的原因:

  • 时出错保存到核心数据我怀疑,最喜欢的程序时,保存对象,以核心数据你没有检查错误 - 或如果你真的这样做,你不知道该怎么处理这个错误。如果你很聪明,你会记录它。最常见的错误是硬盘空间不足。如果对象没有保存在第一个地方,那么当你取回它时它不会在那里。
  • 对象在那里,但被删除。如果您的代码中有任何地方删除了此对象,那么请考虑它在此代码运行之前被删除的可能性。寻找多线程和竞争条件。
  • 该对象尚未保存。如果您在应用程序中有任何多线程,您应该考虑存在竞争条件的可能性。

任何这些情况都会导致0-3%范围内的崩溃。

+0

即使我仍然不确定它为什么会发生,我要将此答案标记为正确。我正在做的是保存在后台上下文中,然后将该上下文合并到主要上下文中。合并发生在主要上下文的performAndWait块中,并且提取也发生在类似的块中。我相信CoreData存在错误,我无法复制它。 –