ios - Core Data private context performAndWait causes debug to crash -
i have problem debugging core data concurrency issues.
in scheme enabled:
-com.apple.coredata.logging.stderr 1 -com.apple.coredata.concurrencydebug 1
i fetch records core data in background thread.
so in uiviewcontroller
create dispatchqueue.global(qos: .background).async
call core data fetch records.
i using parent/child:
func performstationsfetch(filter: string = "") -> [stations] { let privatemoc = nsmanagedobjectcontext(concurrencytype: .privatequeueconcurrencytype) let parentmoc = (uiapplication.shared.delegate as! appdelegate).managedobjectcontext privatemoc.parent = parentmoc var fetchresults: [stations] = [] privatemoc.performandwait { let fetchrequest: nsfetchrequest<stations> = stations.fetchrequest() fetchrequest.predicate = nspredicate(format: "name contains[c] %@", filter) { fetchresults = try privatemoc.fetch(fetchrequest) } catch { print("fetch error") } } return fetchresults }
the problem if call privatemoc.perform
code works fine.
but if call privatemoc.performandwait
code crashes , gives me +[nsmanagedobjectcontext __multithreading_violation_allthatislefttousishonor__]
does have suggestion can problem?
the multi-threading violation occurs when try access results of function. if use perform
, results empty - there no problem. if use performandwait
, returning managedobjects being accessed on wrong thread.
what worse if can bad-access-error if try use objects. managedobjects not normal nsobjects. managedobject objectid , pointer context. whenever needs access properties forwards request context. if context gets removed, objects cannot work. in code context backing results removed memory when function ends. (note: context not removed. in debug environment context may kept around little while. in production released @ end of function).
so accessing results of function illegal 2 reasons - 1) on wrong thread , 2) not having backing context.
there few solutions. 1 copy values need managedobject , return array or strings, or custom object (a nsobject subclass).
another solution fetch on main context around lifetime of application.
alternately can pass context used function. , responsibility of caller ensure context kept around long managedobjects needed.
Comments
Post a Comment