objective c - Realm migration race condition -
how can guarantee realm migrations finish before accessing realm? there seems race condition in migrating realm db , beginning read/write realm. here's issue:
currently setting realm configurations migration closure when user launches app. once realm configuration has been set rlmrealmconfiguration.setdefaultconfiguration(config), set rootviewcontroller , begin accessing realm data.
however, when migration needed, realm accessed before migrations can complete - causing crash (rlmexception: object has been deleted or invalidated). if migration async task no callback, how can guarantee finishes before accessing realm?
here's realm config code:
class func setrealmconfigurationforuser(userid: string) { let config = rlmrealmconfiguration.defaultconfiguration() // migration setup config.schemaversion = 10 config.migrationblock = { migration, oldschemaversion in if oldschemaversion < 2 { migration.enumerateobjects(contactuser.classname()) { oldobject, newobject in // change primary key phonenumber phone_baseid_key let phone = oldobject?["phonenumber"] let baseid = oldobject?["baseid"] newobject?["phone_baseid_key"] = string(phone) + "_" + string(baseid) } } if oldschemaversion < 3 { migration.enumerateobjects(digitscontact.classname()) { oldobject, newobject in newobject?["externalid"] = "" } } if oldschemaversion < 9 { migration.deletedataforclassname(digitscontact.classname()) migration.deletedataforclassname(address.classname()) migration.deletedataforclassname(email.classname()) migration.deletedataforclassname(phonenumber.classname()) } } // use default directory, replace filename userid config.path = (((config.path! nsstring).stringbydeletinglastpathcomponent nsstring) .stringbyappendingpathcomponent(userid) nsstring) .stringbyappendingpathextension("realm") rlmrealmconfiguration.setdefaultconfiguration(config)
according realm's migrations docs, migrations applied when opening realm
configuration on schema version , migration blocks set:
when creating realm configuration, migration block applied update realm given schema version if migration needed.
so if you're calling setrealmconfigurationforuser
asynchronously, concurrent realm accesses use previous default configuration , not see migration block you're in process of defining.
performing migration happens synchronously, either implicitly creating realm migration block in configuration or explicitly calling rlmrealm.migraterealm(_:)
.
all other realm accesses (both reads & writes) blocked on migration completing. long migration block & configuration set before realm initialized, there should no race condition.
ps: you're doing lot of wasted work in migration block when oldschema < 3
because you're setting digitscontact.externalid
properties ""
, delete digitscontact
objects. removing oldschemaversion < 3
conditional , contents lead same result.
pps: there reason you're using realm objective-c swift rather realm swift? realm has dedicated api that's nicer use swift: https://realm.io/docs/swift/latest/
Comments
Post a Comment