Search code examples
iosswiftmagicalrecord

MagicalRecord always faults - unable to read data


No matter what I try when I attempt to access a record returned from mr_findAll, data is always unable to be read.

Please understand I have to redact a bunch of information here so the code looks something like

var results: [Unit] = []

let predicate: NSPredicate? = NSPredicate(format: "abc == %@ AND def == %@", abc, def)

results = Unit.mr_findAll(with: predicate, in:NSManagedObjectContext.mr_default()) as! [Unit]

Three results are returned which is what I expect; If I examine them in the console they look like:

po results

▿ 3 elements

  • 0 : app.Unit: 0x6080002959a0> (entity: Unit; id: 0xd00000000004000a x-coredata://08DA3A42-AFDA-4280-A5B5-4E1267509CFC/Unit/p1> ; data: fault)
  • 1 : app.Unit: 0x608000295b30> (entity: Unit; id: 0xd00000000008000a x-coredata://08DA3A42-AFDA-4280-A5B5-4E1267509CFC/Unit/p2> ; data: fault)
  • 2 : app.Unit: 0x608000295d10> (entity: Unit; id: 0xd0000000000c000a x-coredata://08DA3A42-AFDA-4280-A5B5-4E1267509CFC/Unit/p3> ; data: fault)

I then try and access the results:

for result in results {
        let ghi = result.ghi
        let jkl = result.jkl

At the first possible access to a member of results I get an EXC_BAD_INSTRUCTION and in the inspector I see unable to read data.

I tried numerous ways of 'offsetting' the access to a result as I've read that as soon as you access a member of a faulted record core data will fetch it but to no avail.

If I was using fetch requests I could stipulate

returnsObjectsAsFaults = false

I can't see anything in the MagicalRecord interface which allows the above or something similar.

I'm looking really for

  • a technique that will ensure I don't get faults OR
  • a technique that will absolutely resolve the fault.

Any help much appreciated.


Solution

  • Using NSManagedObjectContext.mr_default() is not thread-safe. It is better to use local context, e.g.:

    var results: [Unit] = []
    MagicalRecord.save(blockAndWait: { (localContext) in
    
        let predicate: NSPredicate? = NSPredicate(format: "abc == %@ AND def == %@", abc, def)
        results = Unit.mr_findAll(with: predicate, in:localContext) as! [Unit]
    })