We in the process of optimizing app startup time and one of the huge slow down come from realm initialization.
We have this code which has been called during didFinishLaunchingWithOptions
RLMRealmConfiguration *config = [[RLMRealmConfiguration alloc] init];
config.schemaVersion = kCurrentSchema;
config.migrationBlock = /* migration task */;
config.fileURL = fileUrl;
config.encryptionKey = encryptionKey;
return config;
During the initialization we try to create RLMRealm
at least once using this configuration to see that we able to open realm or not. If the opening fail then we perform operations to remove Realm folder using NSFileManager
and start anew. After everything is done we set
[RLMRealmConfiguration setDefaultConfiguration:config];
My question is
RLMRealmConfiguration
and initialize RLMRealm
in background thread?RLMRealmConfiguration
create in background thread to main thread to call setDefaultConfiguration
on main thread after the migration is done?.[RLMRealmConfiguration setDefaultConfiguration:config];
on main thread, the migration result from background thread is written to the file or still in memory? If I create another RLMRealm
on main thread directly after setDefaultConfiguration
. Can I access the migrated version? I know about RLMThreadSafeReference
but that only to be used when we know how to access. In my case, we will have too many accesses after the setup.Creating a new RLMRealmConfiguration and calling setDefaultConfiguration are trivial operations. Neither of them trigger migrations.
Migrations don't run until you open a realm.
There are a couple of ways to cause the migration to run in a background thread. I'll show you the easiest way in Swift. You'll have to translate this code to Objective-C:
enum Migrator {
static func migrate(completion: @escaping () -> Void) {
let queue = DispatchQueue(label: "migrator.awesome")
let configuration = Realm.Configuration(
schemaVersion: 13,
migrationBlock: { migration, oldSchemaVersion in
if oldSchemaVersion < 1 {
// ...
}
if oldSchemaVersion < 2 {
// ...
}
if oldSchemaVersion < 3 {
// ...
}
// ...
}
)
Realm.asyncOpen(configuration: configuration, callbackQueue: queue) { result in
Realm.Configuration.defaultConfiguration = configuration
switch result {
case .failure(let error):
print("error", error)
case .success(let realm):
print("realm", realm)
break
}
completion()
}
}
}
asyncOpen
will open a realm and run the migration on the specified queue. In your case, you want to pass in a background queue. Once the migration runs asyncOpen
will invoke the specified callback on the same queue you specified.
One the migration is complete you can switch back to the main thread.
enum Application {
static func execute() {
Migrator.migrate {
DispatchQueue.main.async {
PersonInserter.insertPersons()
PersonPrinter.printPersons()
}
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.