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

对关系建模 - Swift SDK

在此页面上

  • 声明关系属性
  • 定义对一关系属性
  • 定义对多关系属性
  • 定义反向关系属性
  • 定义嵌入式对象属性

提示

另请参阅:

或者,您可以 在 中 定义关系App Services App 。

一对一关系将一个属性映射到另一种对象类型的单个实例。例如,您可以将一个最多有一只伴侣犬的人建模为一对一的关系。

将关系字段设置为 null 会删除对象之间的连接。 但是,Realm 不会删除引用的对象,除非它是嵌入式对象。

重要

对一关系必须是可选的

在对象模型中声明对一关系时,它必须是一个可选属性。如果您尝试建立所需的对一关系,Realm 会在运行时引发异常。

// Dog.h
@interface Dog : RLMObject
@property NSString *name;
// No backlink to person -- one-directional relationship
@end
// Define an RLMArray<Dog> type
RLM_COLLECTION_TYPE(Dog)
// Person.h
@interface Person : RLMObject
@property NSString *name;
// A person can have one dog
@property Dog *dog;
@end
// Dog.m
@implementation Dog
@end
// Person.m
@implementation Person
@end
class Person: Object {
@Persisted var name: String = ""
@Persisted var birthdate: Date = Date(timeIntervalSince1970: 1)
// A person can have one dog
@Persisted var dog: Dog?
}
class Dog: Object {
@Persisted var name: String = ""
@Persisted var age: Int = 0
@Persisted var breed: String?
// No backlink to person -- one-directional relationship
}

提示

另请参阅:

有关对一关系的更多信息,请参阅:对一关系

如果您的应用程序使用 Device Sync,请参阅使用 Device Sync 的模型数据页面,了解有关 Swift 对象模型中的一对一关系如何转换为 Atlas 文档的信息。

一/多对多关系可将一个属性映射到其他对象类型的零个或多个实例。例如,您可将拥有任意数量伴侣犬的一个人构建为一/多对多关系。

使用标有目标类型的RLMArray来定义对多关系属性。

提示

请记住将 RLM_COLLECTION_TYPE()宏与您的类型一起使用,以声明您类型的 RLMArray协议。

// Dog.h
@interface Dog : RLMObject
@property NSString *name;
// No backlink to person -- one-directional relationship
@end
// Define an RLMArray<Dog> type
RLM_COLLECTION_TYPE(Dog)
// Person.h
@interface Person : RLMObject
@property NSString *name;
// A person can have many dogs
@property RLMArray<Dog *><Dog> *dogs;
@end
// Dog.m
@implementation Dog
@end
// Person.m
@implementation Person
@end

使用标有目标类型的列表来定义您的多对多关系属性。

class Person: Object {
@Persisted var name: String = ""
@Persisted var birthdate: Date = Date(timeIntervalSince1970: 1)
// A person can have many dogs
@Persisted var dogs: List<Dog>
}
class Dog: Object {
@Persisted var name: String = ""
@Persisted var age: Int = 0
@Persisted var breed: String?
// No backlink to person -- one-directional relationship
}

提示

另请参阅:

有关对多关系的更多信息,请参阅:对多关系

如果您的应用使用 Device Sync,请参阅使用 Device Sync 的模型数据页面,了解有关 Swift 对象模型中的一对多关系如何转换为 Atlas 文档的信息。

反向关系属性是一种自动反向链接关系。每当在对应的一对多列表或一对一关系属性中添加或删除对象时,Realm 都会自动更新隐式关系。无法手动设置反向关系属性的值。

要定义反向关系,请使用对象模型中的LinkingObjectsLinkingObjects定义指定了反向关系的对象类型和属性名称。

class User: Object {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var _partition: String = ""
@Persisted var name: String = ""
// A user can have many tasks.
@Persisted var tasks: List<Task>
}
class Task: Object {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var _partition: String = ""
@Persisted var text: String = ""
// Backlink to the user. This is automatically updated whenever
// this task is added to or removed from a user's task list.
@Persisted(originProperty: "tasks") var assignee: LinkingObjects<User>
}

要定义反向关系,请在对象模型中使用RLMLinkingObjects 。 覆盖类中的+[RLMObject LinkingObjectProperties]方法,以指定其反向关系的对象类型和属性名称。

// Task.h
@interface Task : RLMObject
@property NSString *description;
@property (readonly) RLMLinkingObjects *assignees;
@end
// Define an RLMArray<Task> type
RLM_COLLECTION_TYPE(Task)
// User.h
@interface User : RLMObject
@property NSString *name;
@property RLMArray<Task *><Task> *tasks;
@end
// Task.m
@implementation Task
+ (NSDictionary *)linkingObjectsProperties {
return @{
@"assignees": [RLMPropertyDescriptor descriptorWithClass:User.class propertyName:@"tasks"],
};
}
@end
// User.m
@implementation User
@end

要定义反向关系,请使用对象模型中的LinkingObjectsLinkingObjects定义指定了反向关系的对象类型和属性名称。

class User: Object {
@objc dynamic var _id: ObjectId = ObjectId.generate()
@objc dynamic var _partition: String = ""
@objc dynamic var name: String = ""
// A user can have many tasks.
let tasks = List<Task>()
override static func primaryKey() -> String? {
return "_id"
}
}
class Task: Object {
@objc dynamic var _id: ObjectId = ObjectId.generate()
@objc dynamic var _partition: String = ""
@objc dynamic var text: String = ""
// Backlink to the user. This is automatically updated whenever
// this task is added to or removed from a user's task list.
let assignee = LinkingObjects(fromType: User.self, property: "tasks")
override static func primaryKey() -> String? {
return "_id"
}
}

提示

另请参阅:

有关反向关系的更多信息,请参阅:反向关系

如果您的应用使用了 Device Sync,则请参阅使用 Device Sync 进行数据建模页面,以了解有关如何将 Swift 对象模型中的逆关系转换为 Atlas 文档的信息。

嵌入式对象将作为单个特定父对象内部的嵌套数据而存在。它会继承其父对象的生命周期,但无法作为独立 Realm 对象存在。如果嵌入式对象的父对象被删除或被新的嵌入式对象实例覆盖,Realm 则会自动删除嵌入式对象。

注意

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

删除Realm 对象时,该对象引用的任何嵌入式对象都会随之删除。 如果希望被引用的对象在删除父对象后仍然存在,则类型根本不应为嵌入式对象。 请改用具有 对一关系 的常规 Realm 对象

您可以通过从RLMEmbeddedObject类派生来定义嵌入式对象。 您可以像使用任何其他类型一样在另一个模型中使用嵌入式对象。

// Define an embedded object
@interface Address : RLMEmbeddedObject
@property NSString *street;
@property NSString *city;
@property NSString *country;
@property NSString *postalCode;
@end
// Enable Address for use in RLMArray
RLM_COLLECTION_TYPE(Address)
@implementation Address
@end
// Define an object with one embedded object
@interface Contact : RLMObject
@property NSString *name;
// Embed a single object.
@property Address *address;
@end
@implementation Contact
@end
// Define an object with an array of embedded objects
@interface Business : RLMObject
@property NSString *name;
// Embed an array of objects
@property RLMArray<Address *><Address> *addresses;
@end

您可以通过从 EmbeddedObject 类派生来定义嵌入式对象。您可以像使用任何其他类型一样在另一个模型中使用嵌入对象。

class Person: Object {
@Persisted(primaryKey: true) var id = 0
@Persisted var name = ""
// To-many relationship - a person can have many dogs
@Persisted var dogs: List<Dog>
// Inverse relationship - a person can be a member of many clubs
@Persisted(originProperty: "members") var clubs: LinkingObjects<DogClub>
// Embed a single object.
// Embedded object properties must be marked optional.
@Persisted var address: Address?
convenience init(name: String, address: Address) {
self.init()
self.name = name
self.address = address
}
}
class DogClub: Object {
@Persisted var name = ""
@Persisted var members: List<Person>
// DogClub has an array of regional office addresses.
// These are embedded objects.
@Persisted var regionalOfficeAddresses: List<Address>
convenience init(name: String, addresses: [Address]) {
self.init()
self.name = name
self.regionalOfficeAddresses.append(objectsIn: addresses)
}
}
class Address: EmbeddedObject {
@Persisted var street: String?
@Persisted var city: String?
@Persisted var country: String?
@Persisted var postalCode: String?
}

提示

另请参阅:

如果您的应用程序使用 Device Sync,请参阅使用 Device Sync 的模型数据页面,了解有关 Swift 对象模型中的嵌入式对象如何转换为 Atlas 文档的信息。

后退

定义对象模型