42

我正在使用领域(当前为 0.85.0),我的应用程序使用数据库来存储特定于用户的数据,例如当前用户的联系人。当用户决定注销时,我需要删除有关用户的每一点信息,而在我看来,最明显、最简单和最干净的事情就是擦除整个领域。不幸的是,Cocoa 库不提供该功能。

目前,我坚持以下

RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
[realm deleteObjects:[MyRealmClass1 allObjectsInRealm:realm]];
[realm deleteObjects:[MyRealmClass2 allObjectsInRealm:realm]];
[realm deleteObjects:[MyRealmClass3 allObjectsInRealm:realm]];
[realm commitWriteTransaction];

有更好的主意吗?

谢谢

4

6 回答 6

55

更新:

自发布以来,添加了一个新方法来删除所有对象(正如 jpsim 已经提到的):

// Obj-C
[realm beginWriteTransaction];
[realm deleteAllObjects];
[realm commitWriteTransaction];


// Swift
try! realm.write {
  realm.deleteAll()
}

请注意,这些方法不会改变数据结构;他们只删除现有记录。如果您希望在不编写迁移的情况下更改领域模型属性(即,就像您在开发中所做的那样),下面的旧解决方案可能仍然有用。

原答案:

您可以简单地删除领域文件本身,就像他们在存储 REST 响应的示例代码中所做的那样:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //...

    // Ensure we start with an empty database
    [[NSFileManager defaultManager] removeItemAtPath:[RLMRealm defaultRealmPath] error:nil];

    //...
}

关于您的评论的更新:

如果您需要确保不再使用领域数据库,您可以使用领域的通知。如果您要openWrites在每次写入之前增加一个计数器,那么您可以在每次写入完成时运行一个块:

self.notificationToken = [realm addNotificationBlock:^(NSString *notification, RLMRealm * realm) {
    if([notification isEqualToString:RLMRealmDidChangeNotification]) {
        self.openWrites = self.openWrites - 1;

        if(!self.openWrites && self.isUserLoggedOut) {
            [[NSFileManager defaultManager] removeItemAtPath:[RLMRealm defaultRealmPath] error:nil];
        }
    }
}];
于 2014-09-26T19:55:03.067 回答
13

RealmSwift:使用标志进行简单重置

尝试了上述答案,但发布了一种更简单的方法来删除领域文件而不是迁移:

Realm.Configuration.defaultConfiguration.deleteRealmIfMigrationNeeded = true

这只是设置一个标志,以便 Realm 可以删除现有文件而不是崩溃try! Realm()

而不是手动删除文件

认为这比上述答案的 Swift 版本更简单:

guard let path = Realm.Configuration.defaultConfiguration.fileURL?.absoluteString else {
    fatalError("no realm path")
}

do {
    try NSFileManager().removeItemAtPath(path)
} catch {
    fatalError("couldn't remove at path")
}
于 2016-11-03T17:26:18.330 回答
11

从领域0.87.0 开始,现在可以通过[[RLMRealm defaultRealm] deleteAllObjects]从写入事务调用来删除所有领域内容。

在 Swift 中,它看起来像这样:RLMRealm.defaultRealm().deleteAllObjects()

于 2014-11-05T17:07:08.843 回答
7

如果有人偶然发现这个问题,正在寻找一种在 Swift 中执行此操作的方法,这只是 DonamiteIsTnt 重写的答案。我已将此功能添加到自定义实用程序类中,以便MyAppUtilities.purgeRealm()在测试和调试期间执行

func purgeRealm() {
    NSFileManager.defaultManager().removeItemAtPath(RLMRealm.defaultRealmPath(), error: nil)
}

注意:如果您发现自己需要清除数据,您可以查看 Realm 的新realm.addOrUpdateObject()功能,该功能允许您用新数据的主键替换现有数据。这样您就不会不断地添加新数据。只是替换“旧”数据。如果您确实使用,请addOrUpdateObject()确保您覆盖模型的primaryKey类函数,以便 Realm 知道哪个属性是您的主键。例如,在 Swift 中:

override class func primaryKey() -> String {
    return "_id"
}
于 2014-10-09T20:48:06.663 回答
1

我遇到了这个有趣的小问题。因此,我在运行架构迁移之前直接查询架构版本。

NSError *error = NULL;
NSUInteger currentSchemaVersion = [RLMRealm schemaVersionAtPath:[RLMRealm defaultRealmPath] error:&error];
if (currentSchemaVersion == RLMNotVersioned) {
    // new db, skip

} else if (currentSchemaVersion < 26) {
    // kill local db
    [[NSFileManager defaultManager] removeItemAtPath:[RLMRealm defaultRealmPath] error:&error];
    if (error) {
        MRLogError(error);
    }

} else if (error) {
    // for good measure...
    MRLogError(error);
}

// perform realm migration
[RLMRealm setSchemaVersion:26
            forRealmAtPath:[RLMRealm defaultRealmPath]
        withMigrationBlock:^(RLMMigration *migration, NSUInteger oldSchemaVersion) {

        }];
于 2015-05-27T12:26:21.630 回答
0

您也可以转到存储领域文件的位置,从那里删除该文件,下次运行应用程序后打开领域时,您将在浏览器中看到空领域数据库。

于 2019-03-07T12:26:13.897 回答