【问题标题】:iOS app crashes with EXC_BREAKPOINT (SIGTRAP)iOS 应用程序因 EXC_BREAKPOINT (SIGTRAP) 而崩溃
【发布时间】:2019-11-23 08:30:03
【问题描述】:

我有一个应用程序在启动时崩溃。我已经确定了问题的根源,但我似乎无法弄清楚如何解决它。让我先解释一下我的工作:

我有一个 LocationManager 来检查用户是否进入某个区域(使用 startRegionMonitoring)。如果是这样,则计划在 5 分钟内触发本地通知。但是,如果此人在 5 分钟内再次离开,则本地通知将被取消。我这样做是因为用户可以通过建筑物而无需实际进入它。当用户自己打开应用程序时,它还会取消任何待处理的通知(在这 5 分钟内)。

发生这种情况时,应用会在启动时崩溃。崩溃报告表明:

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x000000010098b38c
Triggered by Thread:  0

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   GetReminded                     0x000000010098b38c closure #1 in closure #1 in AppDelegate.applicationWillEnterForeground(_:) + 3388300 (AppDelegate.swift:1300)
1   GetReminded                     0x00000001006be738 thunk for @escaping @callee_guaranteed () -> () + 452408 (<compiler-generated>:0)
2   libdispatch.dylib               0x00000001b6448a38 0x1b63e9000 + 391736
3   libdispatch.dylib               0x00000001b64497d4 0x1b63e9000 + 395220
4   libdispatch.dylib               0x00000001b63f7004 0x1b63e9000 + 57348
5   CoreFoundation                  0x00000001b699ac1c 0x1b68f1000 + 695324
6   CoreFoundation                  0x00000001b6995b54 0x1b68f1000 + 674644
7   CoreFoundation                  0x00000001b69950b0 0x1b68f1000 + 671920
8   GraphicsServices                0x00000001b8b9579c 0x1b8b8b000 + 42908
9   UIKitCore                       0x00000001e31c4978 0x1e2908000 + 9161080
10  GetReminded                     0x0000000100681f4c main + 204620 (ExerciseStatistics.swift:219)
11  libdyld.dylib                   0x00000001b645a8e0 0x1b6459000 + 6368

起初,我没有在主线程上执行取消操作——我认为这是导致崩溃的原因。所以我使用了 Dispatch Queue 并认为问题会得到解决,但它仍然存在。我的willEnterForeground代码:

UNUserNotificationCenter.current().getDeliveredNotifications { (notifications: [UNNotification]) in

    DispatchQueue.main.async {
        for notification in notifications {
            if(notification.request.content.userInfo["notificationType"] as! String == "exitReminder" || notification.request.content.userInfo["notificationType"] as! String == "enterReminder") {
                let notificationID = notification.request.identifier
                UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [notificationID])
                UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [notificationID])

            }
        }
    }

}

我不确定如何解决这个问题。知道这个提醒是从后台发送的可能很重要,所以当应用程序不在前台时。我在后台开启了定位服务,当我留在该位置时一切正常,但是当我在这 5 分钟内再次退出时出现问题,因此需要取消通知。

有什么想法吗?

【问题讨论】:

  • 不用担心。感谢您正在调查我的问题。关于可能导致此问题的任何其他想法?
  • 目前还没有任何科,但如果您愿意分享您的项目以深入了解它会非常有帮助
  • 你应该用适当的条件展开替换 as! String
  • 挖进去也发现了这个。我现在正在构建一个带有安全展开(如果允许)的新版本,以了解情况如何。根据我的代码和崩溃报告,这会是问题吗?

标签: ios swift crash crash-dumps dispatch-queue


【解决方案1】:

如果 notificationType 键返回 nil(或字符串以外的其他内容),notification.request.content.userInfo["notificationType"] as! String 将崩溃。没有充分的理由,你不应该使用强制向下转换。

使用防御性编码:

for notification in notifications {
        if let notificationType = notification.request.content.userInfo["notificationType"] as? String { 
             if notificationType == "exitReminder" || notificationType == "enterReminder" {
                let notificationID = notification.request.identifier
                UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [notificationID])
                UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [notificationID])

        }
    }
}

【讨论】:

  • 在我们说话的时候进行调查。当我想到它时,确实应该是它背后的原因。除非我们确定它不能返回 nil,否则强制向下转换绝不是一个好主意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-24
  • 1970-01-01
  • 2013-07-16
  • 1970-01-01
  • 2020-07-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多