ProjectedCollection

public struct ProjectedCollection<Element> : RandomAccessCollection, CustomStringConvertible, ThreadConfined where Element : RealmCollectionValue

ProjectedCollection 是投影属性的一种特殊集合类型,当您要将 Realm 对象的List投影为值列表时,应使用该集合。 您无需手动实例化此类型。 通过在List属性上调用projectTo来使用它:

class PersistedListObject: Object {
    @Persisted public var people: List<CommonPerson>
}

class ListProjection: Projection<PersistedListObject> {
    @Projected(\PersistedListObject.people.projectTo.firstName) var strings: ProjectedCollection<String>
}
  • 声明

    Swift

    public typealias Index = Int
  • 返回列表中与谓词匹配的第一个对象的索引,如果没有对象匹配,则返回nil

    声明

    Swift

    public func index(matching predicate: NSPredicate) -> Int?

    参数

    predicate

    用于筛选对象的谓词。

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

    该区块将与初始结果一起异步调用,然后在每次写事务(write transaction)后再次调用,这会更改collection中的任何对象或collection中的哪些对象。

    传递给区块的change参数以collection内索引的形式报告在每个写事务(write transaction)期间添加、删除或修改了哪些对象。有关所提供变更信息的更多信息,以及如何使用这些信息来更新UITableView的示例,请参阅RealmCollectionChange文档。

    调用区块时,collection将进行全面求值且是最新的,只要不在同一线程上执行写事务(write transaction)或显式调用realm.refresh() ,访问该collection就永远不会执行阻塞工作。

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

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

    class Person: Object {
        @Persisted var dogs: List<Dog>
    }
    class PersonProjection: Projection<Person> {
        @Projected(\Person.dogs.projectTo.name) var dogsNames: ProjectedCollection<String>
    }
    // ...
    let dogsNames = personProjection.dogsNames
    print("dogsNames.count: \(dogsNames?.count)") // => 0
    let token = dogsNames.observe { changes in
        switch changes {
        case .initial(let dogsNames):
            // Will print "dogsNames.count: 1"
            print("dogsNames.count: \(dogsNames.count)")
            break
        case .update:
            // Will not be hit in this example
            break
        case .error:
            break
        }
    }
    try! realm.write {
        let dog = Dog()
        dog.name = "Rex"
        person.dogs.append(dog)
    }
    // end of run loop execution context
    

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

    警告

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

    声明

    Swift

    public func observe(on queue: DispatchQueue?,
                        _ block: @escaping (RealmCollectionChange<ProjectedCollection<Element>>) -> Void) -> NotificationToken

    参数

    queue

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

    block

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

    返回值

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

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

    该区块将与初始结果一起异步调用,然后在每次写事务(write transaction)后再次调用,这会更改collection中的任何对象或collection中的哪些对象。

    传递给区块的change参数以collection内索引的形式报告在每个写事务(write transaction)期间添加、删除或修改了哪些对象。有关所提供变更信息的更多信息,以及如何使用这些信息来更新UITableView的示例,请参阅RealmCollectionChange文档。

    调用区块时,collection将进行全面求值且是最新的,只要不在同一线程上执行写事务(write transaction)或显式调用realm.refresh() ,访问该collection就永远不会执行阻塞工作。

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

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

    class Person: Object {
        @Persisted var dogs: List<Dog>
    }
    class PersonProjection: Projection<Person> {
        @Projected(\Person.dogs.projectTo.name) var dogNames: ProjectedCollection<String>
    }
    // ...
    let dogNames = personProjection.dogNames
    print("dogNames.count: \(dogNames?.count)") // => 0
    let token = dogs.observe { changes in
        switch changes {
        case .initial(let dogNames):
            // Will print "dogNames.count: 1"
            print("dogNames.count: \(dogNames.count)")
            break
        case .update:
            // Will not be hit in this example
            break
        case .error:
            break
        }
    }
    try! realm.write {
        let dog = Dog()
        dog.name = "Rex"
        person.dogs.append(dog)
    }
    // end of run loop execution context
    

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

    class Person: Object {
        @Persisted var dogs: List<Dog>
    }
    class PersonProjection: Projection<Person> {
        @Projected(\Person.dogs.projectTo.name) var dogNames: ProjectedCollection<String>
    }
    // ...
    let dogNames = personProjection.dogNames
    let token = dogNames.observe(keyPaths: ["name"]) { changes in
        switch changes {
        case .initial(let dogNames):
           // ...
        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:
            // ...
        }
    }
    // end of run loop execution context
    

    对此集合中链接到 Dog 的任何其他值的更改都不会trigger该区块。 对正在观察的 Dog 类型集合的任何插入或删除仍会trigger通知。

    注意

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

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

    警告

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

    声明

    Swift

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

    参数

    keyPaths

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

    queue

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

    block

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

    返回值

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

  • 返回位于给定索引处的对象 (get),或替换位于给定索引处的对象 (set)。

    警告

    您只能在写事务(write transaction)期间设置对象。

    声明

    Swift

    public subscript(position: Int) -> Element { get set }

    参数

    index

    要检索或替换的对象的索引。

  • 非空collection中第一个元素的位置。与空collection中的 endIndex 相同。

    声明

    Swift

    public var startIndex: Int { get }
  • 集合的“超过末尾”位置。 endIndex 不是下标的有效参数,但始终可以通过零次或多次应用程序 successor() 从 startIndex 访问 endIndex。

    声明

    Swift

    public var endIndex: Int { get }
  • 管理对象的Realm 。

    声明

    Swift

    public var realm: Realm? { get }
  • 指示是否无法再访问该collection。

    声明

    Swift

    public var isInvalidated: Bool { get }
  • 对象的人类可读描述。

    声明

    Swift

    public var description: String { get }
  • 返回对象在链接对象中的索引,如果该对象不存在,则返回nil

    声明

    Swift

    public func index(of object: Element) -> Int?

    参数

    object

    正在查询其索引的对象。

  • 声明

    Swift

    public var isFrozen: Bool { get }
  • 声明

    Swift

    public func freeze() -> ProjectedCollection<Element>
  • 声明

    Swift

    public func thaw() -> `Self`?