the app im developing intermittently throws the above exception on app launch. Here is the stack trace for the thread that triggered the crash.
0 libobjc.A.dylib 0x00000001bbcaa148 object_getClass + 12 (objc-object.h:237)1 CoreData 0x00000001ae28e6b0 _PFObjectIDFastHash64 + 28 (NSBasicObjectID.m:706)2 CoreFoundation 0x00000001a84af10c __CFBasicHashRehash + 996 (CFBasicHash.c:477)3 CoreFoundation 0x00000001a84b2df4 CFBasicHashRemoveValue + 2352 (CFBasicHash.c:1386)4 CoreFoundation 0x00000001a83d12f8 CFDictionaryRemoveValue + 224 (CFDictionary.c:471)5 CoreData 0x00000001ae1de8e8 -[NSManagedObjectContext(_NSInternalAdditions) _forgetObject:propagateToObjectStore:removeFromRegistry:] + 120 (NSManagedObjectContext.m:5088)6 CoreData 0x00000001ae1be450 -[_PFManagedObjectReferenceQueue _processReferenceQueue:] + 864 (NSManagedObjectContext.m:5077)7 CoreData 0x00000001ae2d6578 __90-[NSManagedObjectContext(_NSInternalNotificationHandling) _registerAsyncReferenceCallback]_block_invoke + 68 (NSManagedObjectContext.m:8825)8 CoreData 0x00000001ae2ccb18 developerSubmittedBlockToNSManagedObjectContextPerform + 156 (NSManagedObjectContext.m:3880)9 libdispatch.dylib 0x00000001a80be280 _dispatch_client_callout + 16 (object.m:559)10 libdispatch.dylib 0x00000001a809a4fc _dispatch_lane_serial_drain$VARIANT$armv81 + 568 (inline_internal.h:2548)11 libdispatch.dylib 0x00000001a809afe8 _dispatch_lane_invoke$VARIANT$armv81 + 404 (queue.c:3862)12 libdispatch.dylib 0x00000001a80a4808 _dispatch_workloop_worker_thread + 692 (queue.c:6590)13 libsystem_pthread.dylib 0x00000001edcd85a4 _pthread_wqthread + 272 (pthread.c:2193)14 libsystem_pthread.dylib 0x00000001edcdb874 start_wqthread + 8
I use a series of interdependent Operations upon app launch to fetch and clean data from CoreData and permissions initialized via Async calls to the server. I use the below CoreDataManager to handle CoreData saving and fetching.
As I said, this problem occurs seemingly at random. Any help would be appreciated.
/// A manager for interfacing with Core Data.////// This class is a singleton, and the instance is accessible via the `shared` property.class CoreDataManager { /// The single shared instance of the `CoreDataManager` class. static let shared = CoreDataManager() /// The underlying `NSManagedObjectContext` that is being used by this manager. let context: NSManagedObjectContext private let container: NSPersistentContainer private init() { container = NSPersistentContainer(name: "FinSiteful") container.loadPersistentStores(completionHandler: { (_, error) in if let error = error as NSError? { fatalError("Unresolved error \(error), \(error.userInfo)") } }) context = container.newBackgroundContext() context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy NotificationCenter.default.addObserver(self, selector: #selector(contextDidSave(_:)), name: Notification.Name.NSManagedObjectContextDidSave, object: nil) } /// This function executes any time the managed object context is saved. /// /// - Important: Other uses of the `notification` paramter /// /// 1. Use `notification.userInfo[NSInsertedObjectsKey] as? Set<NSManagedObject>` to get inserted data /// 2. Use `notification.userInfo[NSDeletedObjectsKey] as? Set<NSManagedObject>` to get deleted data /// 3. Use `notification.userInfo[NSUpdatedObjectsKey] as? Set<NSManagedObject>` to get updated data /// /// - Parameter notification: The `Notification` that contains the data updated, inserted, and/or deleted @objc private func contextDidSave(_ notification: Notification) { print("CoreDataManager: Context did save") } /// Creates a new managed object within the default context. /// /// This method mostly exists for convenience. Below is an example of how to use this method to create /// a new `Transaction` object which can be saved into CoreData. /// ``` /// let trans: Transaction = CoreDataManager.shared.newObject() /// ``` /// /// - Important: The context must be saved after calling this function in order for the object to be permanently /// added to the database. Use the `saveContext()` method for this. /// /// - Returns: A newly created `NSManagedObject`. func newObject<T>() -> T where T: NSManagedObject { T(context: self.context) } /// Executes the provided fetch request to retrieve data from Core Data. /// /// - Parameter request: The `NSFetchRequest` to be executed. /// - Returns: The results of `request`. func fetch<T>(_ request: NSFetchRequest<T>) -> [T] where T: NSManagedObject { do { return try context.fetch(request) } catch { let nserror = error as NSError fatalError("Unresolved error \(nserror), \(nserror.userInfo)") } } /// Convenience wrapper around the context's delete method. /// /// Specifies that the given object should be removed from its persistent store when changes are committed. /// /// - Important: The context must be saved after calling this function in order for the changes to permanently take effect. /// Use the `saveContext()` method for this. /// /// - Parameter object: The object to be removed. func delete(_ object: NSManagedObject) { context.delete(object) } /// Saves any changes in the context to the database. /// /// This method will only attempt to save if there are in fact changes that have been made. /// /// Under normal circumstances, saving the context should never fail. /// So, this method produces a `fatalError` in the event of a failure. func saveContext() { if context.hasChanges { do { try context.save() } catch { let nserror = error as NSError fatalError("Unresolved error \(nserror), \(nserror.userInfo)") } } }}