What is the correct way to use realm in an autoreleasepool?

4.6k views Asked by At

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."

Documentation

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.

1

There are 1 answers

8
TiM On

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.