ios - Core Data Concurrency Debugging -


it's coredatastack file. when run project concurrency debugging app crashes right after pin added. think cause try access data in different thread thread in context created. fix need of data access happens in same thread thread in context created. wrong?

run project -com.apple.coredata.concurrencydebug 1

import coredata  struct coredatastack {      // mark: - properties      private let model: nsmanagedobjectmodel     internal let coordinator: nspersistentstorecoordinator     private let modelurl: url     internal let dburl: url     internal let persistingcontext: nsmanagedobjectcontext     internal let backgroundcontext: nsmanagedobjectcontext     let context: nsmanagedobjectcontext      // mark: - initializers      init?(modelname: string) {          // assumes model in main bundle         guard let modelurl = bundle.main.url(forresource: modelname, withextension: "momd") else {             print("unable find \(modelname)in main bundle")             return nil         }         self.modelurl = modelurl          // try create model url         guard let model = nsmanagedobjectmodel(contentsof: modelurl) else {             print("unable create model \(modelurl)")             return nil         }         self.model = model          // create store coordinator         coordinator = nspersistentstorecoordinator(managedobjectmodel: model)          // create persistingcontext (private queue) , child 1 (main queue)         // create context , add connect coordinator         persistingcontext = nsmanagedobjectcontext(concurrencytype: .privatequeueconcurrencytype)         persistingcontext.persistentstorecoordinator = coordinator          context = nsmanagedobjectcontext(concurrencytype: .mainqueueconcurrencytype)         context.parent = persistingcontext          // create background context child of main context         backgroundcontext = nsmanagedobjectcontext(concurrencytype: .privatequeueconcurrencytype)         backgroundcontext.parent = context          // add sqlite store located in documents folder         let fm = filemanager.default          guard let docurl = fm.urls(for: .documentdirectory, in: .userdomainmask).first else {             print("unable reach documents folder")             return nil         }          self.dburl = docurl.appendingpathcomponent("model.sqlite")          // options migration         let options = [nsinfermappingmodelautomaticallyoption: true,nsmigratepersistentstoresautomaticallyoption: true]          {             try addstorecoordinator(nssqlitestoretype, configuration: nil, storeurl: dburl, options: options [nsobject : anyobject]?)         } catch {             print("unable add store @ \(dburl)")         }     }      // mark: - utils      func addstorecoordinator(_ storetype: string, configuration: string?, storeurl: url, options : [nsobject:anyobject]?) throws {         try coordinator.addpersistentstore(oftype: nssqlitestoretype, configurationname: nil, at: dburl, options: nil)     } }  // mark: - coredatastack (removing data)  internal extension coredatastack  {      func dropalldata() throws {         // delete objects in db. won't delete files,         // leave empty tables.         try coordinator.destroypersistentstore(at: dburl, oftype: nssqlitestoretype , options: nil)         try addstorecoordinator(nssqlitestoretype, configuration: nil, storeurl: dburl, options: nil)     } }  // mark: - coredatastack (batch processing in background)  extension coredatastack {      typealias batch = (_ workercontext: nsmanagedobjectcontext) -> ()      func performbackgroundbatchoperation(_ batch: @escaping batch) {          backgroundcontext.perform() {              batch(self.backgroundcontext)              // save parent context, normal saving             // can work             {                 try self.backgroundcontext.save()             } catch {                 fatalerror("error while saving backgroundcontext: \(error)")             }         }     } }  // mark: - coredatastack (save data)  extension coredatastack {      func save() {         context.performandwait() {             if self.context.haschanges {                 {                     try self.context.save()                 } catch {                     fatalerror("error while saving main context: \(error)")                 }                 self.persistingcontext.perform() {                     {                         try self.persistingcontext.save()                     } catch {                         fatalerror("error while saving persisting context: \(error)")                     }                 }             }         }     }      func autosave(_ delayinseconds : int) {         if delayinseconds > 0 {             {                 try self.context.save()                 print("autosaving")             } catch {                 print("error while autosaving")             }             let delayinnanoseconds = uint64(delayinseconds) * nsec_per_sec             let time = dispatchtime.now() + double(int64(delayinnanoseconds)) / double(nsec_per_sec)              dispatchqueue.main.asyncafter(deadline: time) {                 self.autosave(delayinseconds)             }         }     } } 

make sure make ui changes in main thread.


Comments