我正在用iOS 12.5编写一个Swift XCode应用程序,让你在与联系人之间的“事件”(互动)上做笔记。在做了一些修改之后,在我的手机上启动这个应用程序时,我已经几个月没碰过的应用程序的一部分出现了EXC_BAD_ACCESS错误--这个通知管理器根据你在任何联系人上的最新记录创建了一个提醒。
作为背景,我使用CoreData将应用程序的数据存储在联系人和备注上,使用NSManagedObjects表示联系人对象;每个联系人对象有0到多个事件对象。几个月前,该应用程序在我的iPhone上运行良好,在模拟器上运行良好,因为我最近几天/几周一直在对代码进行更改。我试着用仪器工具检查僵尸和漏洞,结果空手而出。我还试图评估代码行中的变量,导致错误的访问错误,但找不到问题。
在较高级别上,这是导致问题的执行顺序:
Data
func getEvents(last90days: Bool = false) -> [Event] {
var events = [Event]()
let keyDate = Date(timeIntervalSinceNow: -90 * 60 * 60 * 24)
for case let event as Event in (self.events ?? []) { // this is the line where the EXC_BAD_ACCESS occurs. Even if I nil-coalesce above this line separately, the problem still persists.
if last90days && event.timestamp != nil {
if event.timestamp == nil {
continue
}
if event.timestamp! < keyDate {
continue
}
}
events.append(event)
}
return events
}
_Error Message:_Thread 4: EXC_BAD_ACCESS (code=1,address=0x1fa9bf0)堆栈跟踪:
* thread #4, queue = 'com.apple.usernotifications.UNUserNotificationServiceConnection.call-out', stop reason = EXC_BAD_ACCESS (code=1, address=0x1fa9bf0)
frame #0: 0x00000001ace04334 libobjc.A.dylib`object_getMethodImplementation + 48
frame #1: 0x00000001982d7c04 CoreFoundation`_NSIsNSSet + 40
frame #2: 0x00000001981aaf18 CoreFoundation`-[NSMutableSet unionSet:] + 108
frame #3: 0x000000019e3c93b0 CoreData`-[_NSFaultingMutableSet willReadWithContents:] + 636
frame #4: 0x000000019e3e7ff4 CoreData`-[_NSFaultingMutableSet countByEnumeratingWithState:objects:count:] + 48
frame #5: 0x000000019bd12bd0 libswiftFoundation.dylib`Foundation.NSFastEnumerationIterator.next() -> Swift.Optional<Any> + 180
* frame #6: 0x0000000100dbb03c myApp`Contact.getEvents(last90days=false, self=0x0000000281b32f80) at Contact+helpers.swift:48:9
frame #7: 0x0000000100db7bc8 myApp`InteractionAnalyzer.countInteractions(startDate=2022-01-03 04:12:17 UTC, endDate=2022-01-10 04:12:17 UTC, name=nil, onlyIncludeNewSparks=false, excludeNewSparks=false, sparkStartDate=nil, self=0x00000002838feb20) at InteractionAnalyzer.swift:24:48
frame #8: 0x0000000100dfac18 myApp`NotificationManager.getNotificationString(self=0x000000028377a220) at NotificationManager.swift:74:60
frame #9: 0x0000000100dfa368 myApp`NotificationManager.addNotificationRequest(self=0x000000028377a220) at NotificationManager.swift:62:29
frame #10: 0x0000000100df9ab8 myApp`closure #1 in NotificationManager.addReminder(settings=0x0000000281355490, self=0x000000028377a220) at NotificationManager.swift:36:22
frame #11: 0x0000000100df98d4 myApp`thunk for @escaping @callee_guaranteed (@guaranteed UNNotificationSettings) -> () at <compiler-generated>:0
frame #12: 0x000000010146c0b4 libdispatch.dylib`_dispatch_call_block_and_release + 32
frame #13: 0x000000010146dde0 libdispatch.dylib`_dispatch_client_callout + 20
frame #14: 0x0000000101475ef0 libdispatch.dylib`_dispatch_lane_serial_drain + 788
frame #15: 0x0000000101476d48 libdispatch.dylib`_dispatch_lane_invoke + 496
frame #16: 0x0000000101483a50 libdispatch.dylib`_dispatch_workloop_worker_thread + 1600
frame #17: 0x00000001e3f927a4 libsystem_pthread.dylib`_pthread_wqthread + 276
我怎么才能弄清这件事的真相呢?我在EXC_BAD_ACCESS上爬行了很多线程,但都没有用,我希望我只是错过了一些非常简单的东西。
发布于 2022-01-12 07:16:09
堆栈跟踪中的NSFaultingMutableSet指出了从我的核心数据存储区访问数据的问题(例如,像self.events这样的事件对象)。我的通知管理器在一个单独的线程上操作,造成了一种不稳定的情况,在主线程和辅助线程上同时读取和修改Core数据(我还没有为多线程访问正确设置这些数据)。
我能够通过包装Notification代码来解决这个问题,Notification代码访问DispatchQueue.main.async {...}
块中的核心数据对象。还有其他方法可以设置核心数据对象,以便从多个线程访问(例如,Coredata - Multithreading best way),但是这是最简单的解决方案,因为多线程访问不是我要做的事情的优先级。
发布于 2022-01-10 08:01:25
在您的计划中添加添加消毒液,并在模拟器上运行应用程序。Hopofully杀菌剂将更准确地显示代码中数据竞争的位置。
上运行您的应用程序
https://stackoverflow.com/questions/70646762
复制相似问题