如果我将realm实例化为类属性,如何删除Realm?

时间:2017-03-15 16:23:13

标签: ios swift realm

根据Realm团队提供的示例,我已经实例化了这个领域并将其绑定到一个名为“realm”的类变量,如下所示:

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    let realm = try! Realm()

我认为它有意义并使代码更具可读性。但是,我的项目处于早期阶段,对象正在发生很大变化,我试图避免使用此进行迁移:

Realm.Configuration.defaultConfiguration.deleteRealmIfMigrationNeeded = true

当然,这会导致麻烦,因为我在打开docs中明确禁止的Realm之后尝试删除Realm文件。我在UIViewController类中也遵循了类似的设计模式,这使得重构有点麻烦。

问题是:
像我一样将Realm实例绑定到类属性是不好的做法吗?我应该总是引用Realm,让letm = try!当我需要读取对象时,Realm()阻塞?或者有没有办法删除领域而不删除所有类范围的领域实例?

谢谢

2 个答案:

答案 0 :(得分:1)

我使用这种模式:

Singleton DataManager,用于管理Realm访问权限。它可以包装所有try,例如:

class DataManager {
    static let shared = DataManager()

    func add(_ object: Object, update: Bool = true) {
        do {
            let realm = try Realm()
            try realm.write {
                realm.add(object, update: update)
            }
        } catch {
            print (error)
        }
    }

    ...Other shared Realm methods...
}

我还有一个MigrationManager单例,顾名思义,它处理Realm迁移。它的方法很早就被调用 - 远在调用DataManager方法之前

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    ...
    MigrationManager.shared.migrate()
    ...
}

一些MigrationManager代码

class MigrationManager {
    static let shared = MigrationManager()

    let schemaVersion: UInt64 = 3

    private var migrationBlock: MigrationBlock? {
        return { migration, oldSchemaVersion in
        ...
        }
    }

    func migrate() {
        let config = Realm.Configuration(
            schemaVersion: schemaVersion,
            migrationBlock: migrationBlock)

        Realm.Configuration.defaultConfiguration = config
    }
}

答案 1 :(得分:1)

当您调用try! Realm()时,Realm将在内部存储对实例化的Realm对象的缓存引用。这样,在后续时间调用try! Realm()将回收该实例。

因此,存储Realm个实例作为长期对象的属性(例如应用委托),并且只调用try! Realm()时,通常认为是最佳做法。你真正需要的时候。

您应该尽早在应用代理的执行中配置defaultConfiguration

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
    // Configure the default Realm
    let configuration = Realm.Configuration()
    configuration.deleteRealmIfMigrationNeeded = true
    Realm.Configuration.defaultConfiguration = configuration

    return true
}

这样,事后对Realm()的任何调用都将在迁移逻辑上包含删除。在此之前没有理由保存Realm的副本。

如果您正在使用故事板,有时let realm = try! Realm()作为UIViewController子类中的属性可能会在应用委托代表有机会触发之前被调用。在这种情况下,您也可以在配置Realm后在app delegate中手动设置storyboard逻辑。