Миграция области, где инициализировать

Я пытаюсь работать с одним из задокументированных методов переноса базы данных области и установки версии схемы. Тип кода, который я использую:

let config = Realm.Configuration(
    // Set the new schema version. This must be greater than the previously used
    // version (if you've never set a schema version before, the version is 0).
    schemaVersion: 1,

    // Set the block which will be called automatically when opening a Realm with
    // a schema version lower than the one set above
    migrationBlock: { migration, oldSchemaVersion in
        // We haven’t migrated anything yet, so oldSchemaVersion == 0
        if (oldSchemaVersion < 1) {
            // Nothing to do!
            // Realm will automatically detect new properties and removed properties
            // And will update the schema on disk automatically
        }
})

// Tell Realm to use this new configuration object for the default Realm
Realm.Configuration.defaultConfiguration = config

Это кажется довольно стандартным кодом и, похоже, используется другими. Тем не менее, что, кажется, сбивает меня с толку, так это то, что я инициализирую экземпляр Realm, из-за чего настройка схемы не устанавливается или не сохраняется.

с чем я борюсь, так это где установить следующий код:

let uiRealm = try! Realm()
  • Если я помещу это в начало AppDelegate над @UIApplicationMain, оно будет инициализировано слишком рано.
  • Если я создам файл контроллера, в котором я намерен вызвать функцию после миграции, и поставлю инициализатор вверху, он все равно не работает.
  • Если я поместил его в класс ViewController, как в приведенном ниже коде, я получаю сообщение об ошибке. Член экземпляра uiRealm не может использоваться для типа XYZViewController.

    import UIKit
    import RealmSwift
    
    class XYZViewController: UITableViewController,UIPickerViewDataSource,UIPickerViewDelegate {
    
        let uiRealm = try! Realm()
        var scenarios = uiRealm.objects(Scenario).filter("isActive = true ")
    
    }
    

Итак, мой вопрос: есть ли какие-либо рекомендации о том, где инициализировать и как лучше всего мигрировать.


person Michael Moulsdale    schedule 02.10.2016    source источник


Ответы (1)


Вы должны убедиться, что вы установили свой объект Configuration в качестве конфигурации вашего Realm по умолчанию, прежде чем любые другие части вашего кода вызовут Realm().

Лучше всего не держать никаких ссылок на Realm(), если у вас нет очень веской причины. Каждый раз, когда вы вызываете Realm(), он возвращает ранее кэшированный экземпляр объекта, поэтому нет никаких преимуществ в производительности при создании ссылки на экземпляр, а затем привязывании к нему в течение жизненного цикла вашего приложения.

Лучшее место для установки вашего объекта Configuration с информацией о миграции — как можно скорее, до того, как код сможет вызвать Realm(). Так что делегат приложения — хорошее место для этого.

Если у вас есть свойства класса, которые полагаются на Realm(), уже предварительно настроенные, может помочь добавление ключевого слова lazy к этим свойствам, чтобы их создание было отложено до тех пор, пока они вам действительно не понадобятся.

person TiM    schedule 03.10.2016
comment
Спасибо за это, так как мне преобразовать следующее в ленивую инициализацию? сценарии = uiRealm.objects(Scenario).filter(isActive = true ). Если я просто поставлю lazy впереди, я получаю сообщение об ошибке Использование неразрешенного идентификатора uiRealm - person Michael Moulsdale; 22.10.2016
comment
Без проблем! Хм, есть ли причина, по которой вы не можете просто использовать Realm() вместо uiRealm? - person TiM; 23.10.2016
comment
Привет, я обошел это, объявив сценарии var: Results‹Scenario›! вверху, а затем инициализируя область внутри каждой функции. Опять же, я пытался сделать слишком много в качестве глобального съедобного и переместил все в функции. - person Michael Moulsdale; 23.10.2016
comment
Более того. Добавление следующего кода дает нам ленивую версию инициализатора lazy var uiRealm:Realm = { return try! Область() }() - person Michael Moulsdale; 23.10.2016