删除 Realm 对象 - Kotlin SDK
在此页面上
本页介绍如何使用 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 中将保持孤立状态。这是否构成问题将取决于应用程序的需求。
删除 Realm 对象
要从 Realm 中删除特定对象:
使用realm.write()打开写事务 或realm.writeBlocking()。
使用查询 ()在事务的可变域中查询要删除的对象,从而获取活动对象:
将对象类型指定为传递给
query()
的类型参数。(可选)通过指定查询来筛选返回的对象集。如果不包含查询筛选器,则返回指定类型的所有对象。有关使用 Kotlin SDK 进行查询的更多信息,请参阅读取 Realm 对象 - Kotlin SDK。
重要
对象必须是实时的
您只能删除活动对象。如果查询发生在写事务之外,则必须使用
mutableRealm.findLatest()
将冻结对象转换为事务中的活动对象。将查询返回的 RealmResults 集传递给 mutableRealm.delete()。
指定的对象将从 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) }
删除 Realm 中的所有对象
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 }
从集合中删除元素
包含对象的 Realm 集合实例只存储对这些对象的引用。您可以从集合中删除一个或多个引用对象,而不删除对象本身。从集合中删除的对象会保留在 Realm 中,直到您手动予以删除。另外,从 Realm 中删除 Realm 对象也会从包含该对象的集合实例中删除该对象。
从 RealmList 中删除元素
您可以在单个ACID 事务中从RealmList中删除一个或多个元素:
要从列表删除一个元素,请将该元素传递给list. 删除()。
要删除列表中指定索引处的一个元素,请将索引传递给list.removeAt()。
要从列表删除多个元素,请将元素传递给list.removeAll()。
您还可以通过调用 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 中删除元素
您可以在单个事务中从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(混合)属性值
尽管 RealmAny
实例无法存储空值,但可以通过将 null
直接分配给属性来删除 RealmAny
属性值。有关 RealmAny
数据类型的更多信息,请参阅 RealmAny(混合)。
在以下示例中,我们有包含 RealmAny
属性列表的 Frog
对象,并清除了第一个 RealmAny
属性的值:
realm.write { val frog = query<Frog>().find().first() frog.favoriteThings[0] = null }