objective c - Realm crash when invalidating while updating -
i have constant crash on realm when try remove database while i'm still running update events in other thread.
the crash is:
2017-08-14 18:07:56.289 app staging[28264:7828070] *** terminating app due uncaught exception 'rlmexception', reason: 'can add, remove, or create objects in realm in write transaction - call beginwritetransaction on rlmrealm instance first.' *** first throw call stack: ( 0 corefoundation 0x000000010c67fb0b __exceptionpreprocess + 171 1 libobjc.a.dylib 0x000000010c0e4141 objc_exception_throw + 48 2 realm 0x0000000108095f96 _zl27rlmverifyinwritetransactionp8rlmrealm + 86 3 realm 0x000000010809710a rlmcreateobjectinrealmwithvalue + 138 4 realm 0x00000001080820af +[rlmobject createorupdateinrealm:withvalue:] + 607 5 app staging 0x0000000107497ae0 +[realmroundable createorupdateinrealm:withmemberresponse:] + 400 6 app staging 0x0000000107497916 +[realmroundable createorupdatewithmemberresponse:] + 118 7 app staging 0x000000010742a0a0 +[realmstaff createorupdateinrealm:withresponse:incareprovider:] + 352 8 app staging 0x000000010742ab92 +[realmstaff createorupdateinrealm:withstaff:incareprovider:] + 514 9 app staging 0x000000010742a94b +[realmstaff createorupdatestaff:incareprovider:] + 139 10 app staging 0x000000010733b803 -[staffroundabletableviewcontroller updateroundables:fromdataloader:incareprovider:] + 131 11 app staging 0x000000010747ae3a __54-[roundabletableviewcontroller dataloaderdidloaddata:]_block_invoke.324 + 122 12 realm 0x00000001081d01a6 -[rlmrealm transactionwithblock:error:] + 86 13 realm 0x00000001081d010e -[rlmrealm transactionwithblock:] + 62 14 app staging 0x000000010747ab0d __54-[roundabletableviewcontroller dataloaderdidloaddata:]_block_invoke + 765 15 libdispatch.dylib 0x000000010e15c4a6 _dispatch_call_block_and_release + 12 16 libdispatch.dylib 0x000000010e18505c _dispatch_client_callout + 8 17 libdispatch.dylib 0x000000010e164dcd _dispatch_queue_override_invoke + 1321 18 libdispatch.dylib 0x000000010e166ec4 _dispatch_root_queue_drain + 634 19 libdispatch.dylib 0x000000010e166bef _dispatch_worker_thread3 + 123 20 libsystem_pthread.dylib 0x000000010e51c5a2 _pthread_wqthread + 1299 21 libsystem_pthread.dylib 0x000000010e51c07d start_wqthread + 13 ) libc++abi.dylib: terminating uncaught exception of type nsexception
this happens when call:
[realmmanager deleterealm];
which implemented as:
+ (void)deleterealm { @autoreleasepool { [[rlmrealm defaultrealm] invalidate]; // hack force realm clear cache because config cached , crashes because detects encryption key has changed suppress_undeclared_selector_warning([[rlmrealm class] performselector:@selector(resetrealmstate)]); } nsfilemanager *manager = [nsfilemanager defaultmanager]; rlmrealmconfiguration *config = [rlmrealmconfiguration defaultconfiguration]; nsarray<nsurl *> *realmfileurls = @[ config.fileurl, [config.fileurl urlbyappendingpathextension:@"lock"], [config.fileurl urlbyappendingpathextension:@"log_a"], [config.fileurl urlbyappendingpathextension:@"log_b"], [config.fileurl urlbyappendingpathextension:@"note"], [[config.fileurl urlbydeletinglastpathcomponent] urlbyappendingpathcomponent:[nsstring stringwithformat:@"%@.realm.management", [[config.fileurl urlbydeletingpathextension] lastpathcomponent]]] ]; (nsurl *url in realmfileurls) { nserror *error = nil; [manager removeitematurl:url error:&error]; if (error) { // handle error ddlogerror(@"error deleting realm file - %@", error); } } }
my question is: there way stop realm operations before running code.
from realm's documentation on deleting realm files:
because realm avoids copying data memory except when absolutely required, objects managed realm contain references file on disk, , must deallocated before file can safely deleted. includes objects read (or added to) realm,
rlmarray
,rlmresults
, ,rlmthreadsafereference
objects, ,rlmrealm
itself.in practice, means deleting realm file should done either on application startup before have opened realm, or after opening realm within explicit autorelease pool, ensures of realm objects have been deallocated.
removing file while it's still being accessed them on thread lead sorts of problems. calling realm's private methods, such +[rlmrealm resetrealmstate]
, too. i'd suggest doing neither of these things.
you might approach in different ways, depending on motivation removing realm file disk. if can share more information use case might able provide more specific suggestion.
for instance, keep track of whether background threads actively working realm , delete once they're idle. need careful ensure references realm have been dropped @ point remove file, though, otherwise end continuing access now-deleted file via already-open file handle.
alternatively, instead of deleting realm file instead generate new, unique path new realm file. delete realm files not being used when you're sure remainder of app not using them (next launch reliable way of achieving this, or otherwise tying points in app lifecycle know old state can no longer accessed). preference there's no chance of removing file while it's being used. it's fit many apps have concept of logging user out, different realm path per user relatively easy concept grasp.
Comments
Post a Comment