ios - How do you access NSManagedObjects between blocks? -
like title says how 1 go accessing nsmanagedobject has been created in 1 block , needs accessed in other. have following implementation , wondering if it's correct.
__block person *newperson; @weakify(self); [magicalrecord savewithblock:^(nsmanagedobjectcontext *localcontext) { newperson = [person mr_createincontext:localcontext]; newperson.name = @"bob"; } completion:^(bool success, nserror *error) { @strongify(self); // called on main thread personviewcontroller *personvc = [[personviewcontroller alloc] initwithperson:newperson]; [self.navigationcontroller pushviewcontroller:personvc animated:yes]; }];
am correct in not needing access newperson localcontext in completion handler because it'll executed on main thread?
edit
it looks following proposed way:
__block nsmanagedobjectid *newpersonobjectid; @weakify(self); [magicalrecord savewithblock:^(nsmanagedobjectcontext *localcontext) { person *newperson = [person mr_createincontext:localcontext]; newperson.name = @"bob"; newpersonobjectid = newperson.objectid; } completion:^(bool success, nserror *error) { @strongify(self); // called on main thread person *savedperson = [[nsmanagedobjectcontext mr_defaultcontext] objectwithid:newpersonobjectid]; personviewcontroller *personvc = [[personviewcontroller alloc] initwithperson:savedperson]; [self.navigationcontroller pushviewcontroller:personvc animated:yes]; }];
solution
this answer , comments lead following solution. temporaryid being assigned object whilst it's being saved , therefore when trying fetch object tempid exception occurs.
rather creating whole new fetch request can done asking context obtain permanent ids , acquiring permanent id of object. example:
__block nsmanagedobjectid *newpersonobjectid; @weakify(self); [magicalrecord savewithblock:^(nsmanagedobjectcontext *localcontext) { person *newperson = [person mr_createincontext:localcontext]; newperson.name = @"bob"; [localcontext obtainpermanentidsforobjects:@[newperson] error:null]; newpersonobjectid = newperson.objectid; } completion:^(bool success, nserror *error) { @strongify(self); // called on main thread person *savedperson = [[nsmanagedobjectcontext mr_defaultcontext] objectwithid:newpersonobjectid]; personviewcontroller *personvc = [[personviewcontroller alloc] initwithperson:savedperson]; [self.navigationcontroller pushviewcontroller:personvc animated:yes]; }];
you can't directly pass managed objects between contexts. each nsmanagedobject
can accessed own context.
you'll need pass objectid
completion block, have main context fetch object calling 1 of following methods:
-(nsmanagedobject *)objectwithid:(nsmanagedobjectid *)objectid
this create fault object specified objectid, whether or not exists in store. if doesn't exist, fires fault fail exception.
-(nsmanagedobject *)existingobjectwithid:(nsmanagedobjectid *)objectid error:(nserror **)error
this fetch object store has id, or return nil if doesn't exist. unlike objectwithid
, object won't faulted; attributes have been retrieved.
in either case, local context must have saved person
object store main context able fetch it.
more details objectid
can found in core data programming guide
edit user asking question
this answer , comments lead correct solution. temporaryid being assigned object whilst it's being saved , therefore when trying fetch object tempid exception occurs.
rather creating whole new fetch request can done asking context obtain permanent ids , acquiring permanent id of object. example:
__block nsmanagedobjectid *newpersonobjectid; @weakify(self); [magicalrecord savewithblock:^(nsmanagedobjectcontext *localcontext) { person *newperson = [person mr_createincontext:localcontext]; newperson.name = @"bob"; [localcontext obtainpermanentidsforobjects:@[newperson] error:null]; newpersonobjectid = newperson.objectid; } completion:^(bool success, nserror *error) { @strongify(self); // called on main thread person *savedperson = [[nsmanagedobjectcontext mr_defaultcontext] objectwithid:newpersonobjectid]; personviewcontroller *personvc = [[personviewcontroller alloc] initwithperson:savedperson]; [self.navigationcontroller pushviewcontroller:personvc animated:yes]; }];
Comments
Post a Comment