As the title says, unless I have at least one notification block added to an in-memory Realm, data disappears as soon as the function call from which it has been inserted returns.
I just need to attach an observer to any one Realm instance, then everything works.
I have a static constant containing my configuration defined like this:
class RealmStore : NSObject {
static let configuration:Realm.Configuration = Realm.Configuration(inMemoryIdentifier: "InMemoryRealm")
...
I have a single point of entry for write operations:
private static func performWriteOperation(op: (Realm) -> Void) {
let realm = try! Realm(configuration: self.configuration)
do {
try realm.write {
op(realm)
}
} catch {
fatalError("Write operation failed")
}
print("Total leagues ", realm.objects(League.self).count)
}
(I have made sure that it's ALWAYS being called on the main thread, although this doesn't seem to make any difference)
This is how insertion of a league looks:
private static func insert(fromNotification notification: PriceService.Notification, replaceAllData:Bool) {
performWriteOperation(op:insert(notification))
}
private static func insert(_ notification: PriceService.Notification) -> (Realm) -> Void {
return { realm in
switch notification {
case .newLeagues(let notification):
notification.leagues.forEach { self.insert($0)(realm) }
(etc...)
}
private static func insert(_ notification: LeagueNotification) -> (Realm) -> Void {
return { realm in
let league = League.with(notification: notification)
realm.add(league, update: true)
}
}
(again, this is being called on the main thread)
I receive a lot of different entities after the leagues. This is my console output *WITHOUT any notificationBlocks attached to the realm or any results:*
Handling: .newLeagues(132)
Total leagues 132
Handling: .newTeams1333
Total leagues 0
Handling: .newEvents(2110)
Total leagues 0
Handling: .updatedLines
Total leagues 0
Handling: .updatedLines
Total leagues 0
Handling: .updatedLines
Total leagues 0
Handling: .updatedLines
Total leagues 0
Handling: .updatedLines
Total leagues 0
As soon as I add a notificationBlock of some kind:
let realm = try! Realm(configuration: RealmStore.configuration)
notificationBlock = realm.addNotificationBlock { _ in }
Everything seems to work as expected:
Handling: .newLeagues(132)
Total leagues 132
Handling: .newTeams1333
Total leagues 132
Handling: .newEvents(2109)
Total leagues 132
Handling: .newEvents(2109)
Total leagues 132
Handling: .updatedLines
Total leagues 132
Handling: .updatedLines
Total leagues 132`
I'm just creating adding an empty notificationBlock directly on a realm instance but observing on a Results object has the same effect. ..
Also, if I change my configuration to a file-based one, the problem goes away.
Realm version: realm-swift-2.4.2
Xcode version: 8.2.1
iOS version: 10.1, Same behaviour with the Simulator
Dependency manager + version: Downloaded binaries from GitHub
Hi @kasperwelner. Thanks for reaching out about this. I'll have one of the engineers review what you've shared and follow-up soon. Cheers!
The documentation on in-memory Realms contains the following notice:
Notice: When all in-memory Realm instances with a particular identifier go out of scope with no references, all data is freed for that Realm. It is recommended that you hold onto a strong reference to any created in-memory Realms for the duration of your app.
In the code snippets you've provided it looks like the Realm instances you create don't outlive the functions that open them. Notifications change things slightly as they inherently extend the lifetime of the Realm.
Making a strong reference to the Realm solved it. Thx 馃憤
Awesome, glad to hear @kasperwelner. We're here if you need anything else! :)
@istx25 I'm having the same problem but I'm running all my in-memory realms on non-ui threads. If I create a strongly referenced in-memory realm i cannot use it in other threads as it is not thread safe. But if I don't have a strong reference I'll lose that realm and all the data with it as mentioned above.
How to solve this issue?
Most helpful comment
@istx25 I'm having the same problem but I'm running all my in-memory realms on non-ui threads. If I create a strongly referenced in-memory realm i cannot use it in other threads as it is not thread safe. But if I don't have a strong reference I'll lose that realm and all the data with it as mentioned above.
How to solve this issue?