地图

public final class Map<Key, Value> : RLMSwiftCollectionBase where Key : _MapKey, Value : RealmCollectionValue
extension Map: ObservableObject, RealmSubscribable
extension Map: Sequence
extension Map: RealmKeyedCollection
extension Map: Decodable where Key: Decodable, Value: Decodable
extension Map: Encodable where Key: Encodable, Value: Encodable

Map 是一个键值存储container,用于存储支持的 Realm 类型。

Map 是一种泛型类型,可对其存储的类型进行参数化。 它可以是 对象 子类,也可以是以下类型之一:Bool、Int、Int8、Int16、Int32、Int64、Float、Double、String、Data、Date、Decimal128 和 ObjectId(及其可选版本)

注意

Object之外,上述类型的可选版本仅在非同步 Realm 中受支持。

Map 仅支持String作为键。 Realm 不允许在字典键中使用.$字符。

与 Swift 的原生collection不同, Map是一种引用类型,只有当托管它们的 Realm 以只读方式打开时,它们才是不可变的。

可以使用与Results<Value>相同的谓词对 Map 进行过滤和排序。

属性

初始化器

  • 创建一个Map ,用于保存类型为Value的 Realm 模型对象。

    声明

    迅速

    public override init()

数数

变更

  • 更新存储在映射中的给定键的值,如果键不存在,则添加新的键值对。

    注意

    如果添加到映射的值是非托管对象,而映射是托管对象,则该非托管对象将添加到 Realm。

    警告

    此方法只能在写事务(write transaction)期间调用。

    声明

    迅速

    public func updateValue(_ value: Value, forKey key: Key)

    参数

    value

    值的键路径谓词。

    forKey

    排序的方向。

  • 将给定字典合并到此映射中,使用组合闭包确定任何重复键的值。

    如果dictionary包含此映射中已存在的键,则将使用映射中当前的值和字典中的值调用combine 。 闭包返回的值将存储在该键的映射中。

    注意

    如果添加到映射的值是非托管对象,而映射是托管对象,则该非托管对象将添加到 Realm。

    警告

    此方法只能在写事务(write transaction)期间在托管 Map 上调用。

    声明

    迅速

    public func merge<S>(_ sequence: S, uniquingKeysWith combine: (Value, Value) throws -> Value) rethrows
            where S: Sequence, S.Element == (key: Key, value: Value)

    参数

    dictionary

    要合并到此映射中的字典。

    combine

    为任何重复键获取当前值和新值的闭包。 闭包返回最终映射的所需值。

  • 将给定映射合并到此映射中,使用组合闭包确定任何重复键的值。

    如果other包含此映射中已存在的键,则将使用此映射中的当前值和另一个映射中的值调用combine 。 闭包返回的值将存储在该键的映射中。

    注意

    如果添加到映射的值是非托管对象,而映射是托管对象,则该非托管对象将添加到 Realm。

    警告

    此方法只能在写事务(write transaction)期间在托管 Map 上调用。

    声明

    迅速

    public func merge(_ other: Map<Key, Value>, uniquingKeysWith combine: (Value, Value) throws -> Value) rethrows

    参数

    other

    要合并到此地图中的地图。

    combine

    为任何重复键获取当前值和新值的闭包。 闭包返回最终映射的所需值。

  • 仅当给定键存在于映射中时,才会删除该键及其关联对象。 如果该键不存在,则不会修改映射。

    警告

    此方法只能在写事务(write transaction)期间调用。

    声明

    迅速

    public func removeObject(for key: Key)
  • 从地图中删除所有对象。 对象不会从管理它们的 Realm 中删除。

    警告

    此方法只能在写事务(write transaction)期间调用。

    声明

    迅速

    public func removeAll()
  • 返回给定键的值,或者在下标用于分配时为键设置值。

    注意

    注意:如果添加到映射的值是非托管对象,而映射是托管对象,则该非托管对象将添加到 Realm。

    注意

    注意:如果为某个键分配的值为nil ,则该键将从地图中删除。

    警告

    此方法只能在写事务(write transaction)期间调用。

    声明

    迅速

    public subscript(key: Key) -> Value? { get set }

    参数

    key

    密钥。

  • 如果指定键存在于地图中,则返回其AnyObject类型。

    声明

    迅速

    @objc
    public func object(forKey key: AnyObject) -> AnyObject?

    参数

    key

    所需值的属性的键。

KVC

  • 如果指定键存在于地图中,则返回其Value类型。

    请注意,使用键值编码时,键必须是字符串。

    声明

    迅速

    @nonobjc
    public func value(forKey key: String) -> AnyObject?

    参数

    key

    所需值的属性的键。

  • 如果指定键存在于地图中,则返回其Value类型。

    声明

    迅速

    @nonobjc
    public func value(forKeyPath keyPath: String) -> AnyObject?

    参数

    keyPath

    所需值的属性的键。

  • 将给定的键值对添加到映射,或更新给定的键(如果已存在)。

    警告

    只能在写事务(write transaction)期间调用此方法。

    声明

    迅速

    public func setValue(_ value: Any?, forKey key: String)

    参数

    value

    对象值。

    key

    应在每个对象上设置其值的属性的名称。

过滤

  • 返回一个Results ,其中包含映射中与给定谓词匹配的所有值。

    注意

    这将返回映射中的值,而不是键值对。

    声明

    迅速

    public func filter(_ predicate: NSPredicate) -> Results<Value>

    参数

    predicate

    用于筛选值的谓词。

  • 返回一个Results ,其中包含地图中与给定查询匹配的所有值。

    注意

    这只应与使用@Persistable属性声明的类一起使用。

    • 用法:

      myMap.where {
      ($0.fooCol > 5) && ($0.barCol == "foobar")
      }
      

    注意

    有关可用查询操作的更多信息,请参阅Query

    声明

    迅速

    public func `where`(_ isIncluded: ((Query<Value>) -> Query<Bool>)) -> Results<Value>

    参数

    isIncluded

    用于筛选对象的查询闭包。

  • 返回一个布尔值,指示 Map 是否包含满足给定谓词的键值对

    声明

    迅速

    public func contains(where predicate: @escaping (_ key: Key, _ value: Value) -> Bool) -> Bool

    参数

    where

    一个闭包,用于测试给定映射的任何键对是否表示匹配项。

排序

  • 返回包含映射中对象的Results ,但已排序。

    对象根据其值进行排序。 例如,要对Date的映射从最新到最旧进行排序,您可以调用dates.sorted(ascending: true)

    声明

    迅速

    public func sorted(ascending: Bool = true) -> Results<Value>

    参数

    ascending

    排序的方向。

  • 返回包含映射中对象的Results ,但已排序。

    对象根据给定键路径的值进行排序。 例如,要根据age属性对Student的映射从新到旧进行排序,您可以调用students.sorted(byKeyPath: "age", ascending: true)

    警告

    字典只能按布尔值、 DateNSDate 、单精度和双精度浮点、整数和字符串类型的属性进行排序。

    声明

    迅速

    public func sorted(byKeyPath keyPath: String, ascending: Bool = true) -> Results<Value>

    参数

    keyPath

    排序依据的键路径。

    ascending

    排序的方向。

  • 返回包含映射中对象的Results ,但已排序。

    警告

    映射只能按布尔值、 DateNSDate 、单精度和双精度浮点、整数和字符串类型的属性进行排序。

    声明

    迅速

    public func sorted<S: Sequence>(by sortDescriptors: S) -> Results<Value>
        where S.Iterator.Element == SortDescriptor

聚合操作

  • 返回collection中所有对象的给定属性的最小值,如果地图为空,则返回nil

    警告

    只能指定类型符合MinMaxType协议的属性。

    声明

    迅速

    public func min<T>(ofProperty property: String) -> T? where T : _HasPersistedType, T.PersistedType : MinMaxType

    参数

    property

    所需最小值的属性名称。

  • 返回collection中对象的属性的最大值,如果地图为空,则返回nil

    警告

    只能指定类型符合MinMaxType协议的属性。

    声明

    迅速

    public func max<T>(ofProperty property: String) -> T? where T : _HasPersistedType, T.PersistedType : MinMaxType

    参数

    property

    所需最小值的属性名称。

  • 返回collection中对象的给定属性的总和,如果地图为空,则返回nil

    警告

    只能使用符合AddableType协议的类型的属性名称。

    声明

    迅速

    public func sum<T>(ofProperty property: String) -> T where T : _HasPersistedType, T.PersistedType : AddableType

    参数

    property

    符合AddableType的属性名称,用于计算总和。

  • 返回collection中对象的属性的平均值,如果地图为空,则返回nil

    警告

    只能指定类型符合AddableType协议的属性。

    声明

    迅速

    public func average<T>(ofProperty property: String) -> T? where T : _HasPersistedType, T.PersistedType : AddableType

    参数

    property

    应对其值求和的属性的名称。

通知

  • 注册一个区块,以便在每次地图更改时调用。

    该区块将与初始映射一起异步调用,然后在每次更改映射中的任何键或值的写事务(write transaction)后再次调用。

    传递给区块的change参数以映射中键的形式报告在每个写事务期间添加、删除或修改了哪些键值对。

    如果未指定队列,则将通过标准事件循环传递通知,因此当事件循环被其他活动阻塞时无法传递通知。如果给出了队列,则将通知传递到该队列。 当无法立即传递通知时,可以将多个通知合并为一个通知。 这可以包括初始collection的通知。

    例如,以下代码在添加通知块后立即执行写事务(write transaction),因此没有机会首先传递初始通知。因此,初始通知将反映写事务后 Realm 的状态。

    let myStringMap = myObject.stringMap
    print("myStringMap.count: \(myStringMap?.count)") // => 0
    let token = myStringMap.observe { changes in
        switch changes {
        case .initial(let myStringMap):
            // Will print "myStringMap.count: 1"
            print("myStringMap.count: \(myStringMap.count)")
           print("Dog Name: \(myStringMap["nameOfDog"])") // => "Rex"
            break
        case .update:
            // Will not be hit in this example
            break
        case .error:
            break
        }
    }
    try! realm.write {
        myStringMap["nameOfDog"] = "Rex"
    }
    

    如果未给出键路径,则在所有对象属性以及任何嵌套、链接对象的属性的任何插入、修改或删除操作时都会执行该区块。 如果提供了一个或多个关键路径,则将调用该区块以进行仅在所提供的关键路径上发生的更改。 例如,如果:

    class Dog: Object {
        @Persisted var name: String
        @Persisted var age: Int
        @Persisted var toys: List<Toy>
    }
    // ...
    let dogs = myObject.mapOfDogs
    let token = dogs.observe(keyPaths: ["name"]) { changes in
        switch changes {
        case .initial(let dogs):
           // ...
        case .update:
           // This case is hit:
           // - after the token is initialized
           // - when the name property of an object in the
           // collection is modified
           // - when an element is inserted or removed
           //   from the collection.
           // This block is not triggered:
           // - when a value other than name is modified on
           //   one of the elements.
        case .error:
            // ...
        }
    }
    
    • 如果观察到的键路径为["toys.brand"] ,则对collection任何元素上的toys列表进行的任何插入或删除操作都会trigger该区块。 对链接到此collection中的Dog的任何Toybrand值进行更改都会trigger该区块。在链接到此collection中的Dog的任何Toy上,对brand以外的值进行更改都不会trigger该区块。对所观察到的Dog类型collection的任何插入或删除也会trigger通知。
    • 如果在上面的示例中观察到了["toys"]键路径,那么针对集合中的任何元素对toys列表进行的任何插入、删除或修改都会触发区块。 对链接到此collection中的Dog的任何Toy的任何值进行更改都不会trigger该区块。对正在观察的Dog类型集合的任何插入或删除仍会触发通知。

    注意

    同一对象上的多个通知令牌(针对单独的键路径进行过滤)不会进行排他性过滤。如果一项键路径变更符合一个通知令牌的条件,则该对象的所有通知令牌块都将执行。

    只要您希望将更新发送到区块,就必须保留返回的令牌。 要停止接收更新,请对令牌调用invalidate()

    警告

    在写事务(write transaction)期间或当包含的 Realm 为只读时,无法调用此方法。

    注意

    keyPaths 参数是指collection类型的对象属性,而不是Map 中的特定键/值对。

    声明

    迅速

    public func observe(keyPaths: [String]? = nil,
                        on queue: DispatchQueue? = nil,
                        _ block: @escaping (RealmMapChange<Map>) -> Void)
    -> NotificationToken

    参数

    keyPaths

    只有键路径数组中包含的属性在修改时才会触发区块。 如果为nil ,则对象上的任何属性更改都会发送通知。 与有效属性不对应的字符串键路径将引发异常。 有关关联属性的更多详细信息,请参阅上述描述。

    queue

    用于接收通知的串行调度队列。 如果为nil ,则通知将传递到当前线程。

    block

    发生更改时要调用的区块。

    返回值

    只要您希望传递更新,就必须持有的令牌。

  • observe(keyPaths:on:_:) 异步(Asynchronous)

    注册一个区块,以便在每次地图更改时调用。

    该区块将在具有初始映射的 actor 上异步调用,然后在每次写入事务后再次调用,这会更改映射中存在的键或任何对象的值。

    传递给区块的change参数以映射中键的形式报告在每个写事务期间添加、删除或修改了哪些键值对。

    通知将传递到该 actor 执行器上与给定 actor 隔离的函数。 如果 actor 正在执行阻塞工作,则多个通知可能会合并为一个通知。 这可以包括带有初始collection的通知,并且仅报告传递初始通知后发生的写入的更改。

    如果未给出键路径,则在所有对象属性以及任何嵌套、链接对象的属性的任何插入、修改或删除操作时都会执行该区块。 如果提供了一个或多个关键路径,则将调用该区块以进行仅在所提供的关键路径上发生的更改。 例如,如果:

    class Dog: Object {
        @Persisted var name: String
        @Persisted var age: Int
        @Persisted var toys: List<Toy>
    }
    // ...
    let dogs = myObject.mapOfDogs
    let token = dogs.observe(keyPaths: ["name"], on: actor) { actor, changes in
        switch changes {
        case .initial(let dogs):
            // ...
        case .update:
            // This case is hit:
            // - after the token is initialized
            // - when the name property of an object in the collection is modified
            // - when an element is inserted or removed from the collection.
            // This block is not triggered:
            // - when a value other than name is modified on one of the elements.
        case .error:
            // No longer possible and left for backwards compatibility
        }
    }
    
    • 如果观察到的键路径为["toys.brand"] ,则对collection任何元素上的toys列表进行的任何插入或删除操作都会trigger该区块。 对链接到此collection中的Dog的任何Toybrand值进行更改都会trigger该区块。在链接到此collection中的Dog的任何Toy上,对brand以外的值进行更改都不会trigger该区块。对所观察到的Dog类型collection的任何插入或删除也会trigger通知。
    • 如果在上面的示例中观察到了["toys"]键路径,那么针对集合中的任何元素对toys列表进行的任何插入、删除或修改都会触发区块。 对链接到此collection中的Dog的任何Toy的任何值进行更改都不会trigger该区块。对正在观察的Dog类型集合的任何插入或删除仍会触发通知。

    只要您希望将更新发送到区块,就必须保留返回的令牌。 要停止接收更新,请对令牌调用invalidate()

    警告

    在写事务(write transaction)期间或当包含的 Realm 为只读时,无法调用此方法。

    注意

    keyPaths 参数是指collection类型的对象属性,而不是Map 中的特定键/值对。

    声明

    迅速

    @available(macOS 10.15, tvOS 13.0, iOS 13.0, watchOS 6.0, *)
    @_unsafeInheritExecutor
    public func observe<A: Actor>(
        keyPaths: [String]? = nil, on actor: A,
        _ block: @Sendable @escaping (isolated A, RealmMapChange<Map>) -> Void
    ) async -> NotificationToken

    参数

    keyPaths

    只有键路径数组中包含的属性在修改时才会触发区块。 如果为nil ,则对象上的任何属性更改都会发送通知。 与有效属性不对应的字符串键路径将引发异常。 有关关联属性的更多详细信息,请参阅上述描述。

    actor

    应向其传递通知的 actor。 此 actor 作为独立参数传递给区块,允许您从回调中同步访问 actor。

    block

    发生更改时要调用的区块。

    返回值

    只要您希望传递更新,就必须持有的令牌。

  • observe(keyPaths:on:_:) 异步(Asynchronous)

    注册一个区块,以便在每次地图更改时调用。

    该区块将在具有初始映射的 actor 上异步调用,然后在每次写入事务后再次调用,这会更改映射中存在的键或任何对象的值。

    传递给区块的change参数以映射中键的形式报告在每个写事务期间添加、删除或修改了哪些键值对。

    通知将传递到该 actor 执行器上与给定 actor 隔离的函数。 如果 actor 正在执行阻塞工作,则多个通知可能会合并为一个通知。 这可以包括带有初始collection的通知,并且仅报告传递初始通知后发生的写入的更改。

    对于仅在提供的键路径上发生的更改,将调用该区块。 例如,如果:

    class Dog: Object {
        @Persisted var name: String
        @Persisted var age: Int
        @Persisted var toys: List<Toy>
    }
    // ...
    let dogs = myObject.mapOfDogs
    let token = dogs.observe(keyPaths: [\.name], on: actor) { actor, changes in
        switch changes {
        case .initial(let dogs):
            // ...
        case .update:
            // This case is hit:
            // - after the token is initialized
            // - when the name property of an object in the collection is modified
            // - when an element is inserted or removed from the collection.
            // This block is not triggered:
            // - when a value other than name is modified on one of the elements.
        case .error:
            // No longer possible and left for backwards compatibility
        }
    }
    
    • 如果观察到的键路径为[\.toys.brand] ,则对collection任何元素上的toys列表进行的任何插入或删除操作都会trigger该区块。 对链接到此collection中的Dog的任何Toybrand值进行更改都会trigger该区块。在链接到此collection中的Dog的任何Toy上,对brand以外的值进行更改都不会trigger该区块。对所观察到的Dog类型collection的任何插入或删除也会trigger通知。
    • 如果在上面的示例中观察到了[\.toys]键路径,那么针对集合中的任何元素对toys列表进行的任何插入、删除或修改都会触发区块。 对链接到此collection中的Dog的任何Toy的任何值进行更改都不会trigger该区块。对正在观察的Dog类型集合的任何插入或删除仍会触发通知。

    只要您希望将更新发送到区块,就必须保留返回的令牌。 要停止接收更新,请对令牌调用invalidate()

    警告

    在写事务(write transaction)期间或当包含的 Realm 为只读时,无法调用此方法。

    注意

    keyPaths 参数是指collection类型的对象属性,而不是Map 中的特定键/值对。

    声明

    迅速

    @available(macOS 10.15, tvOS 13.0, iOS 13.0, watchOS 6.0, *)
    @_unsafeInheritExecutor
    public func observe<A: Actor>(
        keyPaths: [PartialKeyPath<Value.Wrapped>], on actor: A,
        _ block: @Sendable @escaping (isolated A, RealmMapChange<Map>) -> Void
    ) async -> NotificationToken where Value: OptionalProtocol, Value.Wrapped: ObjectBase

    参数

    keyPaths

    只有键路径数组中包含的属性在修改时才会触发区块。 如果为nil ,则对象上的任何属性更改都会发送通知。 与有效属性不对应的字符串键路径将引发异常。 有关关联属性的更多详细信息,请参阅上述描述。

    actor

    应向其传递通知的 actor。 此 actor 作为独立参数传递给区块,允许您从回调中同步访问 actor。

    block

    发生更改时要调用的区块。

    返回值

    只要您希望传递更新,就必须持有的令牌。

冻结对象

  • 指示Map是否被冻结。

    冻结的Map是不可变的,可以从任何线程访问。 冻结的Map是通过在托管的实时Map上调用-freeze来创建的。 非托管Map永远不会被冻结。

    声明

    迅速

    public var isFrozen: Bool { get }
  • 返回Map的冻结(不可变)快照。

    冻结副本是不可变的Map ,其中包含与此Map当前包含的数据相同的数据,但在写入包含的 Realm 时不会更新。 与活动的Map不同,冻结的Map可以从任何线程访问。

    警告

    在写事务(write transaction)期间或当包含的 Realm 为只读时,无法调用此方法。

    警告

    此方法只能在托管Map上调用。

    警告

    在 Realm 上执行写事务时长时间持有冻结的Map可能会导致 Realm 文件过大。 有关更多信息,请参阅RLMRealmConfiguration.maximumNumberOfActiveVersions

    声明

    迅速

    public func freeze() -> Map
  • 返回此冻结Map的活动版本。

    此方法解析对同一冻结Map的实时副本的引用。 如果在实时Map上调用,则会自行返回。

    声明

    迅速

    public func thaw() -> Map?
  • 返回 Map 中包含的对象的人类可读描述。

    声明

    迅速

    public override var description: String { get }

地图

  • 每次collection更改时发出 Void 的发布者。

    尽管有这个名称,但它实际上是在collection发生更改发出的。

    声明

    迅速

    public var objectWillChange: RealmPublishers.WillChange<Map> { get }

序列支持

Key : DecodableValue : Decodable的情况下可用

Key : EncodableValue : Encodable的情况下可用