Reputation: 1296
This is what the documentation has to say about accessing a realm using GCD:
"You should use an explicit autorelease pool when accessing a Realm from a dispatch queue."
I have used this practice in my app but I am suddenly seeing the following message in my console: "RLMRealm instance was deallocated during a write transaction".
It is not throwing an error, it is just silently printing it to the console. Nothing is written to the database.
I found this issue on github that seems very similar.
My question is now: What practice should I use? The one used in the Realm documentation or the answer found in the github issue?
Thanks for any clarification.
Upvotes: 11
Views: 4859
Reputation: 16011
GCD blocks manage their own @autorelease
pools, but there's no guarantee when that will actually occur, and it may happen a fair amount of time after the block itself has completed (See this SO answer)
Realm maintains read-locks on all of its instances across threads (This is how it's possible to still read from Realm while a write transaction is open on another thread), so as a result, it's recommended to explicitly dealloc a Realm instance when you're done so that disk space can be reclaimed.
If you don't use an @autoreleasepool
, nothing too bad will happen; just the size of the Realm file on disk will increase.
Best practice is to use an @autoreleasepool
block, and to ensure that all of your write transactions are committed inside that block.
@autoreleasepool {
let realm = try! Realm()
try! realm.write {
// ... perform changes
}
}
It's usually recommended to use realm.write
over beginWrite()
/commitWrite()
since it lets you safely perform transactions without forgetting to commit, and also provides some extra error handling.
The problem with the issue on GitHub was that there was a logic path that would cause the @autoreleasepool
to exit before the write transaction had been committed. In this case, you need to review your code logic and make sure you haven't got anything similar.
Upvotes: 13