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

Popular posts from this blog

python Tkinter Capturing keyboard events save as one single string -

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

javascript - Z-index in d3.js -