ProjectionObservable

public protocol ProjectionObservable : AnyObject, ThreadConfined

类型已擦除投影。

ProjectionObservable 是一个组合发布者

ProjectionObservable

  • 注册一个区块,以便在每次投影的底层对象发生变化时进行调用。

    在每个写入事务后,将异步调用该区块,该写入事务会删除底层对象或修改对象的任何投影属性,包括将属性设置为其现有值的自分配。

    对于在不同线程或不同进程中执行的写事务(write transaction),当管理 Realm(自动)刷新到包含更改的版本时,将调用该区块,而对于本地写事务(write transaction),将在提交写事务(write transaction)后的未来某个时间点调用该区块。

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

    class Person: Object {
        @Persisted var firstName: String
        @Persisted var lastName = ""
        @Persisted public var friends: List<Person>
    }
    
    class PersonProjection: Projection<Person> {
        @Projected(\Person.firstName) var name
        @Projected(\Person.lastName.localizedUppercase) var lastNameCaps
        @Projected(\Person.friends.projectTo.firstName) var firstFriendsName: ProjectedCollection<String>
    }
    
    let token = projectedPerson.observe(keyPaths: ["name"], { changes in
       // ...
    })
    
    • 上述通知块会在投影的底层Person对象的Person.firstName属性发生更改时触发,但不会在对Person.lastNamePerson.friends列表进行任何更改时触发。
    • 通知块会因PersonProjection.name属性更改而触发,但不会因其他投影的属性更改而触发。
    • 如果观察到的键路径为["firstFriendsName"] ,则对friends列表的firstName的任何插入、删除或修改都将trigger区块。对someFriend.lastName的更改不会trigger该区块(其中someFriendfriends中包含的元素)

    注意

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

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

    ListResults不同,添加新的通知块后,不会执行“初始”回调。

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

    在回调块中捕获对观察到的对象的强引用是安全的。 由于回调由返回的令牌而不是对象本身保留,因此不存在保留周期。

    警告

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

    警告

    对于原始属性具有相同根属性名称的投影属性,这将为每个投影属性触发PropertyChange ,即使更改仅对应于其中一个属性。对于以下Projection对象“swift class PersonProjection: Projection { @Projected(\Person.firstName) var name @Projected(\Person.address.country)originCountry @Projected(\Person.address.phone.number) mobile }

       let token = projectedPerson.observe { changes in
           if case .change(_, let propertyChanges) = changes {
               propertyChanges[0].newValue as? String, "Winterfell" // Will notify the new value
               propertyChanges[1].newValue as? String, "555-555-555" // Will notify with the current value, which hasn't change.
           }
       })
    
       try realm.write {
           person.address.country = "Winterfell"
       }
       ```
    

    声明

    迅速

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

    参数

    keyPaths

    只有键路径数组中包含的属性在修改时才会触发区块。如果为nil ,则对象上任何预计的属性更改都会发送通知。与有效投影属性不对应的字符串键路径将引发异常。

    queue

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

    block

    要调用的区块,其中包含有关对象更改的信息。

    返回值

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

  • 注册一个区块,以便在每次投影的底层对象发生变化时进行调用。

    在每个写入事务后,将异步调用该区块,该写入事务会删除底层对象或修改对象的任何投影属性,包括将属性设置为其现有值的自分配。

    对于在不同线程或不同进程中执行的写事务(write transaction),当管理 Realm(自动)刷新到包含更改的版本时,将调用该区块,而对于本地写事务(write transaction),将在提交写事务(write transaction)后的未来某个时间点调用该区块。

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

    class Person: Object {
        @Persisted var firstName: String
        @Persisted var lastName = ""
        @Persisted public var friends: List<Person>
    }
    
    class PersonProjection: Projection<Person> {
        @Projected(\Person.firstName) var name
        @Projected(\Person.lastName.localizedUppercase) var lastNameCaps
        @Projected(\Person.friends.projectTo.firstName) var firstFriendsName: ProjectedCollection<String>
    }
    
    let token = projectedPerson.observe(keyPaths: [\PersonProjection.name], { changes in
       // ...
    })
    
    • 上述通知块会在对象的firstName属性发生更改时触发,但不会在lastNamefriends列表发生任何更改时触发。
    • 如果观察到的键路径为[\PersonProjection.firstFriendsName] ,则对friends列表的firstName的任何插入、删除或修改都将trigger区块。对someFriend.lastName的更改不会trigger该区块(其中someFriendfriends中包含的元素)

    注意

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

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

    ListResults不同,添加新的通知块后,不会执行“初始”回调。

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

    在回调块中捕获对观察到的对象的强引用是安全的。 由于回调由返回的令牌而不是对象本身保留,因此不存在保留周期。

    警告

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

    声明

    迅速

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

    参数

    keyPaths

    只有键路径数组中包含的属性在修改时才会触发区块。如果为nil ,则对象上任何预计的属性更改都会发送通知。与有效投影属性不对应的字符串键路径将引发异常。

    queue

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

    block

    要调用的区块,其中包含有关对象更改的信息。

    返回值

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

  • observe(keyPaths:on:_:) 扩展方法,异步

    注册一个区块,以便在每次投影的底层对象发生变化时进行调用。

    每次写事务(write transaction)后,将在 actor 上异步调用该区块,该写事务(write transaction)会删除底层对象或修改对象的任何投影属性,包括将属性设置为其现有值的自分配。

    对于在不同线程或不同进程中执行的写事务(write transaction),当管理 Realm(自动)刷新到包含更改的版本时,将调用该区块,而对于本地写事务(write transaction),将在提交写事务(write transaction)后的未来某个时间点调用该区块。

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

    class Person: Object {
        @Persisted var firstName: String
        @Persisted var lastName = ""
        @Persisted public var friends: List<Person>
    }
    
    class PersonProjection: Projection<Person> {
        @Projected(\Person.firstName) var name
        @Projected(\Person.lastName.localizedUppercase) var lastNameCaps
        @Projected(\Person.friends.projectTo.firstName) var firstFriendsName: ProjectedCollection<String>
    }
    
    let token = projectedPerson.observe(keyPaths: ["name"], { changes in
       // ...
    })
    
    • 上述通知块会在投影的底层Person对象的Person.firstName属性发生更改时触发,但不会在对Person.lastNamePerson.friends列表进行任何更改时触发。
    • 通知块会因PersonProjection.name属性更改而触发,但不会因其他投影的属性更改而触发。
    • 如果观察到的键路径为["firstFriendsName"] ,则对friends列表的firstName的任何插入、删除或修改都将trigger区块。对someFriend.lastName的更改不会trigger该区块(其中someFriendfriends中包含的元素)

    通知将传递到该 actor 执行器上与给定 actor 隔离的函数。 如果 actor 正在执行阻塞工作,则多个通知可能会合并为一个通知。

    与collection通知不同,它没有“初始”通知,并且该函数返回的时间与首次捕获更改的时间之间没有间隔。

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

    警告

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

    声明

    迅速

    @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, ObjectChange<Self>) -> Void
    ) async -> NotificationToken

    参数

    keyPaths

    只有键路径数组中包含的属性在修改时才会触发区块。如果为nil ,则对象上任何预计的属性更改都会发送通知。与有效投影属性不对应的字符串键路径将引发异常。

    actor

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

    block

    要调用的区块,其中包含有关对象更改的信息。

    返回值

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

  • observe(keyPaths:on:_:) 扩展方法,异步

    注册一个区块,以便在每次投影的底层对象发生变化时进行调用。

    每次写事务(write transaction)后,将在 actor 上异步调用该区块,该写事务(write transaction)会删除底层对象或修改对象的任何投影属性,包括将属性设置为其现有值的自分配。

    对于在不同线程或不同进程中执行的写事务(write transaction),当管理 Realm(自动)刷新到包含更改的版本时,将调用该区块,而对于本地写事务(write transaction),将在提交写事务(write transaction)后的未来某个时间点调用该区块。

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

    class Person: Object {
        @Persisted var firstName: String
        @Persisted var lastName = ""
        @Persisted public var friends: List<Person>
    }
    
    class PersonProjection: Projection<Person> {
        @Projected(\Person.firstName) var name
        @Projected(\Person.lastName.localizedUppercase) var lastNameCaps
        @Projected(\Person.friends.projectTo.firstName) var firstFriendsName: ProjectedCollection<String>
    }
    
    let token = projectedPerson.observe(keyPaths: [\PersonProjection.name], { changes in
       // ...
    })
    
    • 上述通知块会在投影的底层Person对象的Person.firstName属性发生更改时触发,但不会在对Person.lastNamePerson.friends列表进行任何更改时触发。
    • 通知块会因PersonProjection.name属性更改而触发,但不会因其他投影的属性更改而触发。
    • 如果观察到的键路径为[\.firstFriendsName] ,则对friends列表的firstName的任何插入、删除或修改都将trigger区块。对someFriend.lastName的更改不会trigger该区块(其中someFriendfriends中包含的元素)

    通知将传递到该 actor 执行器上与给定 actor 隔离的函数。 如果 actor 正在执行阻塞工作,则多个通知可能会合并为一个通知。

    与collection通知不同,它没有“初始”通知,并且该函数返回的时间与首次捕获更改的时间之间没有间隔。

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

    警告

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

    声明

    迅速

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

    参数

    keyPaths

    只有键路径数组中包含的属性在修改时才会触发区块。如果为nil ,则对象上任何预计的属性更改都会发送通知。与有效投影属性不对应的字符串键路径将引发异常。

    actor

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

    block

    要调用的区块,其中包含有关对象更改的信息。

    返回值

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