Docs 菜单
Docs 主页
/ /
Atlas Device SDKs
/ / /

删除 Realm 对象 - Kotlin SDK

在此页面上

  • 删除操作
  • 相关对象和参考文献
  • 删除 Realm 对象
  • 删除单个对象
  • 删除多个对象
  • 删除某一类型的所有对象
  • 删除 Realm 中的所有对象
  • 删除相关对象
  • 删除某一对象及其相关对象
  • 删除嵌入式对象
  • 从集合中删除元素
  • 从 RealmList 中删除元素
  • 从 RealmSet 中删除元素
  • 删除字典键/值
  • 删除 RealmAny(混合)属性值

本页介绍如何使用 Kotlin SDK 从本地或同步 Realm 删除对象。

您可以选择从 Realm 中删除单个对象、多个对象或所有对象。删除对象后,就不能再访问或修改该对象了。如果尝试使用已删除的对象,Realm 会引发错误。

从 Realm 中删除对象不会删除 Realm 文件或影响 Realm 模式。它仅从 Realm 中删除对象实例。如果要删除 Realm 文件本身,请参阅删除 Realm - Kotlin SDK

注意

写入同步 Realm

对于本地和同步 Realm,从 Realm 中删除对象的语法是相同的。但是,还需要考虑其他因素来确定同步 Realm 中的删除操作是否成功。请参阅向同步 Realm 中写入对象 - Kotlin SDK,了解详情。

所有修改域的操作(包括删除操作)都必须在写事务(write transaction)内执行。 写事务会传递给 Realm 的 写入()writeBlocking()方法。 在此回调中,您可以访问权限MutableRealm实例,然后删除域中的对象。 有关写入事务以及Realm如何处理这些事务的更多信息,请参阅写事务。

您只能删除活动对象,这些对象只能在写事务(write transaction)内部访问。 您可以在ACID 事务中使用mutableRealm.findLatest()将冻结对象转换为活动对象。

例子

删除前转换冻结对象

val frozenFrog = realm.query<Frog>("name == $0", "Kermit").find().firstOrNull()
// Open a write transaction
realm.writeBlocking {
// Get the live frog object with findLatest(), then delete it
if (frozenFrog != null) {
findLatest(frozenFrog)
?.also { delete(it) }
}
}

当您删除与另一个对象有关系属性的对象时,Realm 不会自动删除该相关对象的实例。相反,Realm 只删除对另一个对象的引用。被引用的对象保留在 Realm 中,但无法再通过父属性查询到。

唯一的例外是相关对象是嵌入对象。删除与 EmbeddedRealmObject 有关系的对象时,Realm 会自动以层叠删除的方式删除嵌入对象。有关详细信息,请参阅本页的“删除嵌入对象”部分。

如果要在删除父对象时删除任何相关对象,我们建议执行链式删除。 链式删除包括通过遍历依赖项并在删除父对象。 有关链式删除的更多信息,请参阅本页的删除对象及其相关对象部分。

如果您未自行删除这些相关对象,它们在您的 Realm 中将保持孤立状态。这是否构成问题将取决于应用程序的需求。

要从 Realm 中删除特定对象:

  1. 使用realm.write()打开写事务 或realm.writeBlocking()。

  2. 使用查询 ()在事务的可变域中查询要删除的对象,从而获取活动对象:

    1. 将对象类型指定为传递给 query() 的类型参数。

    2. (可选)通过指定查询来筛选返回的对象集。如果不包含查询筛选器,则返回指定类型的所有对象。有关使用 Kotlin SDK 进行查询的更多信息,请参阅读取 Realm 对象 - Kotlin SDK

    重要

    对象必须是实时的

    您只能删除活动对象。如果查询发生在写事务之外,则必须使用 mutableRealm.findLatest() 将冻结对象转换为事务中的活动对象。

  3. 将查询返回的 RealmResults 集传递给 mutableRealm.delete()。

  4. 指定的对象将从 Realm 中删除,并且无法再访问或修改。如果尝试使用已删除的对象,Realm 会引发错误。

    如果任何已删除的对象与另一个对象有关系, Realm仅删除对另一个对象的引用。 被引用的对象保留在域中,但无法再通过已删除的父属性查询。 有关更多信息,请参阅删除对象及其相关对象部分。

提示

您可以通过调用isValid()检查对象是否仍然有效。 已删除的对象返回false

如需删除单个 RealmObject 对象,请使用筛选器查询对象类型,筛选器会返回要删除的特定对象。

提示

使用独特的识别信息

我们建议使用唯一标识信息(如主键值)进行筛选,以确保查询返回正确的对象。

在以下示例中,我们查询带有特定主键的 Frog 对象,然后将返回的对象传递给 mutableRealm.delete() 以将其从 Realm 中删除:

// Open a write transaction
realm.write {
// Query the Frog type and filter by primary key value
val frogToDelete: Frog = query<Frog>("_id == $0", PRIMARY_KEY_VALUE).find().first()
// Pass the query results to delete()
delete(frogToDelete)
}

如需同时删除多个对象,可将对象类型传递给 query(),并指定查询,返回要删除的所有对象。

在以下示例中,我们先查询 species 为“牛蛙”的前三个 Frog 对象,然后将结果传递给 mutableRealm.delete(),将其从 Realm 中删除:

// Open a write transaction
realm.write {
// Query by species and limit to 3 results
val bullfrogsToDelete: RealmResults<Frog> = query<Frog>("species == 'bullfrog' LIMIT(3)").find()
// Pass the query results to delete()
delete(bullfrogsToDelete)
}

要同时从 Realm 中删除特定类型的所有对象,请将对象类型传递给 query() 并将查询过滤器留空以返回该类型的所有对象。

在以下示例中,我们查询所有 Frog 对象,然后将结果传递给 mutableRealm.delete(),以便将它们从 Realm 中全部删除:

// Open a write transaction
realm.write {
// Query Frog type with no filter to return all frog objects
val frogsLeftInTheRealm = query<Frog>().find()
// Pass the query results to delete()
delete(frogsLeftInTheRealm)
}

Kotlin SDK 允许您删除所有类型的所有托管对象,这对于在原型设计时快速清理 Realm 非常有用。这不会影响 Realm 模式或不受 Realm 管理的任何对象。

要同时删除域中的所有对象,请调用 mutableRealm.deleteAll()。这将删除所有类型的所有对象。

在以下示例中,我们使用 deleteAll() 从 Realm 中删除所有对象:

// Open a write transaction
realm.write {
// Delete all objects from the realm
deleteAll()
}

提示

在开发中使用 deleteAll()

deleteAll() 方法可在开发过程中快速清除 Realm。例如,较之编写迁移以将对象更新到新模式,先删除所有对象再使用应用程序自身重新生成这些对象可能速度更快。

删除父对象不会自动删除与其相关的任何对象,除非相关对象已嵌入。相反,Realm 仅删除对相关对象的引用。

在以下示例中,我们有一个包含 Pond 对象列表的 Frog 对象。删除 Frog 对象后,我们将确认所有 Pond 对象仍然保留在 Realm 中:

// Open a write transaction
realm.write {
// Query for the parent frog object with ponds
val parentObject = query<Frog>("_id == $0", PRIMARY_KEY_VALUE).find().first()
assertEquals(2, parentObject.favoritePonds.size)
// Delete the frog and all references to ponds
delete(parentObject)
// Confirm pond objects are still in the realm
val ponds = query<Pond>().find()
assertEquals(2, ponds.size)
}

要在删除父对象时删除相关对象,您必须自己手动删除相关对象。我们建议采用链式删除:首先查询要删除的父对象,然后遍历父对象的关系并删除每个相关对象。最后,删除父对象本身。

在以下示例中,我们查询名为 "Kermit" 的Frog 对象,然后循环访问该对象的 favoritePonds 属性并删除每个 Pond 对象。接着,我们删除 Frog 对象本身:

realm.write {
// Query for the parent frog object with ponds
val frog = query<Frog>("name == $0", "Kermit").find().first()
val ponds = frog.favoritePonds
// Iterate over the list and delete each pond object
if (ponds.isNotEmpty()) {
ponds.forEach { pond ->
delete(pond)
}
}
// Delete the parent frog object
val frogToDelete = findLatest(frog)
if (frogToDelete != null) {
delete(frogToDelete)
}
}

警告

Realm 对嵌入式对象使用级联删除

删除 Realm 对象时,Realm 会自动删除该对象引用的任何嵌入式对象。如果希望被引用的对象在父对象被删除后仍然存在,可以改用具有对一关系的常规 Realm 对象。

您可以通过父对象以层叠删除的方式删除嵌入对象,也可以直接删除嵌入对象。

  • 要通过父对象删除嵌入式对象,请获取并删除父对象。Realm 会自动从该 Realm 中删除其所有嵌入式对象。

  • 直接删除嵌入对象实例

    • 获取并删除特定的嵌入式对象。

    • 清除父对象对嵌入式对象的引用,也将删除嵌入式对象实例。

在以下示例中,我们有一个包含嵌入式 EmbeddedAddress 对象列表的 Business 对象。我们查询并删除 Business 对象,这会自动删除其所有嵌入的 EmbeddedAddress 对象:

// Delete the parent object
realm.write {
val businessToDelete = query<Business>("name == $0", "Big Frog Corp.").find().first()
// Delete the parent object (deletes all embedded objects)
delete(businessToDelete)
}

在以下示例中,有一个包含嵌入式 EmbeddedAddress 对象的 Contact 对象。我们直接删除一个 EmbeddedAddress 对象,并通过父对象删除另一个对象:

// Delete an embedded object directly
realm.write {
val addressToDelete = query<EmbeddedAddress>("street == $0", "456 Lily Pad Ln").find().first()
// Delete the embedded object (nullifies the parent property)
delete(addressToDelete)
}
// Delete an embedded object through the parent
realm.write {
val propertyToClear = query<Contact>("name == $0", "Kermit").find().first()
// Clear the parent property (deletes the embedded object instance)
propertyToClear.address = null
}

提示

获取嵌入对象的父对象

您可以使用parent()获取嵌入式对象的唯一父对象。

包含对象的 Realm 集合实例只存储对这些对象的引用。您可以从集合中删除一个或多个引用对象,而不删除对象本身。从集合中删除的对象会保留在 Realm 中,直到您手动予以删除。另外,从 Realm 中删除 Realm 对象也会从包含该对象的集合实例中删除该对象。

您可以在单个ACID 事务中从RealmList中删除一个或多个元素:

您还可以通过调用 list.clear() 一次性删除 所有 列表元素。

在以下示例中,我们有一个包含 Pond 对象列表的 Forest 对象。我们通过一系列操作删除列表元素,直到列表为空:

// Open a write transaction
realm.write {
// Query for the parent forest object
val forest = query<Forest>("name == $0", "Hundred Acre Wood").find().first()
val forestPonds = forest.nearbyPonds
assertEquals(5, forestPonds.size)
// Remove the first pond in the list
val removeFirstPond = forestPonds.first()
forestPonds.remove(removeFirstPond)
assertEquals(4, forestPonds.size)
// Remove the pond at index 2 in the list
forestPonds.removeAt(2)
assertEquals(3, forestPonds.size)
// Remove the remaining three ponds in the list
forestPonds.removeAll(forestPonds)
assertEquals(0, forestPonds.size)
}

在以下示例中,我们有一个包含 Pond 对象列表的 Forest 对象。我们使用 list.clear() 方法删除所有列表元素:

// Open a write transaction
realm.write {
val forest = query<Forest>("name == $0", "Hundred Acre Wood").find().first()
val forestPonds = forest.nearbyPonds
assertEquals(5, forestPonds.size)
// Clear all ponds from the list
forestPonds.clear()
assertEquals(0, forestPonds.size)
}

您可以在单个事务中从RealmSet 中删除一个或多个元素:

  • 要从集合中删除一个元素,请将要删除的元素传递给set.remove()。

  • 要从集合中删除多个元素,请将要删除的元素传递给 set.removeAll()。

还可以通过调用 set.clear() 一次性删除 所有 集合元素。

在以下示例中,我们有一个包含 Snack 对象集的 Frog 对象。我们通过一系列操作删除该对象集的元素,直到该对象集为空:

// Open a write transaction
realm.write {
// Query for the parent frog object
val myFrog = query<RealmSet_Frog>("name == $0", "Kermit").find().first()
val snackSet = myFrog.favoriteSnacks
assertEquals(3, snackSet.size)
// Remove one snack from the set
snackSet.remove(snackSet.first { it.name == "Flies" })
assertEquals(2, snackSet.size)
// Remove the remaining two snacks from the set
val allSnacks = findLatest(myFrog)!!.favoriteSnacks
snackSet.removeAll(allSnacks)
assertEquals(0, snackSet.size)
}

在以下示例中,我们有一个包含 Snack 对象集的 Frog 对象。我们使用 set.clear() 方法删除对象集中的所有元素:

realm.write {
val myFrog = realm.query<RealmSet_Frog>("name == $0", "Kermit").find().first()
val snackSet = findLatest(myFrog)!!.favoriteSnacks
assertEquals(3, snackSet.size)
// Clear all snacks from the set
snackSet.clear()
assertEquals(0, snackSet.size)
}

可以通过多种方式删除 RealmDictionary 条目:

  • 要删除值但保留键,请将键设置为 null(字典的值必须可为 null)

  • 要移除键和值,请将键传递给 remove()

您还可以通过调用 clear() 来删除 所有 键和值。

在以下示例中,我们有一个包含 String 值字典的 Frog 对象。我们在一系列操作中删除字典元素,直到字典为空:

// Find frogs who have forests with favorite ponds
val thisFrog = realm.query<Frog>("favoritePondsByForest.@count > 1").find().first()
// Set an optional value for a key to null if the key exists
if (thisFrog.favoritePondsByForest.containsKey("Hundred Acre Wood")) {
realm.write {
val mutableFrog = findLatest(thisFrog)
if (mutableFrog != null) {
mutableFrog.favoritePondsByForest["Hundred Acre Wood"] = null
}
}
}
realm.write {
// Remove a key and its value
findLatest(thisFrog)?.favoritePondsByForest?.remove("Lothlorien")
// Remove all keys and values
findLatest(thisFrog)?.favoritePondsByForest?.clear()
assertTrue(thisFrogUpdated.favoritePondsByForest.isEmpty())
}

尽管 RealmAny 实例无法存储空值,但可以通过将 null 直接分配给属性来删除 RealmAny 属性值。有关 RealmAny 数据类型的更多信息,请参阅 RealmAny(混合)。

在以下示例中,我们有包含 RealmAny 属性列表的 Frog 对象,并清除了第一个 RealmAny 属性的值:

realm.write {
val frog = query<Frog>().find().first()
frog.favoriteThings[0] = null
}

后退

Update