mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-01-16 14:06:53 +01:00
Make ObjectPublishers even lighter by lazy-loading observers
This commit is contained in:
@@ -145,6 +145,12 @@ extension NSManagedObjectContext {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func objectsDidChangeObserver<U: AnyObject>(remove: U) {
|
||||
|
||||
_ = self.userInfo(for: .objectsChangeObserver(U.self), initialize: { nil as Any? })
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
@@ -195,6 +195,7 @@ public final class ObjectPublisher<O: DynamicObject>: ObjectRepresentation, Hash
|
||||
|
||||
deinit {
|
||||
|
||||
self.context.objectsDidChangeObserver(remove: self)
|
||||
self.observers.removeAllObjects()
|
||||
}
|
||||
|
||||
@@ -221,30 +222,36 @@ public final class ObjectPublisher<O: DynamicObject>: ObjectRepresentation, Hash
|
||||
|
||||
self.rawObjectWillChange = nil
|
||||
}
|
||||
self.$lazySnapshot.initialize({ initializer(objectID, context) })
|
||||
|
||||
context.objectsDidChangeObserver(for: self).addObserver(self) { [weak self] (updatedIDs, deletedIDs) in
|
||||
self.$lazySnapshot.initialize { [weak self] in
|
||||
|
||||
guard let self = self else {
|
||||
|
||||
return
|
||||
return initializer(objectID, context)
|
||||
}
|
||||
if deletedIDs.contains(objectID) {
|
||||
context.objectsDidChangeObserver(for: self).addObserver(self) { [weak self] (updatedIDs, deletedIDs) in
|
||||
|
||||
self.object = nil
|
||||
guard let self = self else {
|
||||
|
||||
self.willChange()
|
||||
self.$lazySnapshot.reset({ nil })
|
||||
self.didChange()
|
||||
self.notifyObservers()
|
||||
}
|
||||
else if updatedIDs.contains(objectID) {
|
||||
|
||||
self.willChange()
|
||||
self.$lazySnapshot.reset({ initializer(objectID, context) })
|
||||
self.didChange()
|
||||
self.notifyObservers()
|
||||
return
|
||||
}
|
||||
if deletedIDs.contains(objectID) {
|
||||
|
||||
self.object = nil
|
||||
|
||||
self.willChange()
|
||||
self.$lazySnapshot.reset({ nil })
|
||||
self.didChange()
|
||||
self.notifyObservers()
|
||||
}
|
||||
else if updatedIDs.contains(objectID) {
|
||||
|
||||
self.willChange()
|
||||
self.$lazySnapshot.reset({ initializer(objectID, context) })
|
||||
self.didChange()
|
||||
self.notifyObservers()
|
||||
}
|
||||
}
|
||||
return initializer(objectID, context)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -107,6 +107,7 @@ public struct ObjectSnapshot<O: DynamicObject>: ObjectRepresentation, Hashable {
|
||||
return nil
|
||||
}
|
||||
self.id = objectID
|
||||
self.context = context
|
||||
self.values = values
|
||||
}
|
||||
|
||||
@@ -114,6 +115,7 @@ public struct ObjectSnapshot<O: DynamicObject>: ObjectRepresentation, Hashable {
|
||||
// MARK: Private
|
||||
|
||||
private let id: O.ObjectID
|
||||
private let context: NSManagedObjectContext
|
||||
private var values: [String: Any]
|
||||
|
||||
private var valuesRef: NSDictionary {
|
||||
@@ -214,51 +216,59 @@ extension ObjectSnapshot where O: CoreStoreObject {
|
||||
/**
|
||||
Returns the value for the property identified by a given key.
|
||||
*/
|
||||
public subscript<OBase, D>(dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToOne<D>>) -> D.ObjectID? {
|
||||
public subscript<OBase, D>(dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToOne<D>>) -> ObjectPublisher<D>? {
|
||||
|
||||
get {
|
||||
|
||||
let key = String(keyPath: member)
|
||||
return self.values[key] as! D.ObjectID?
|
||||
guard let id = self.values[key] as! D.ObjectID? else {
|
||||
|
||||
return nil
|
||||
}
|
||||
return self.context.objectPublisher(objectID: id)
|
||||
}
|
||||
set {
|
||||
|
||||
let key = String(keyPath: member)
|
||||
self.values[key] = newValue
|
||||
self.values[key] = newValue?.objectID()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the value for the property identified by a given key.
|
||||
*/
|
||||
public subscript<OBase, D>(dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToManyOrdered<D>>) -> [D.ObjectID] {
|
||||
public subscript<OBase, D>(dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToManyOrdered<D>>) -> [ObjectPublisher<D>] {
|
||||
|
||||
get {
|
||||
|
||||
let key = String(keyPath: member)
|
||||
return self.values[key] as! [D.ObjectID]
|
||||
let context = self.context
|
||||
let ids = self.values[key] as! [D.ObjectID]
|
||||
return ids.map(context.objectPublisher(objectID:))
|
||||
}
|
||||
set {
|
||||
|
||||
let key = String(keyPath: member)
|
||||
self.values[key] = newValue
|
||||
self.values[key] = newValue.map({ $0.objectID() })
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the value for the property identified by a given key.
|
||||
*/
|
||||
public subscript<OBase, D>(dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToManyUnordered<D>>) -> Set<D.ObjectID> {
|
||||
public subscript<OBase, D>(dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToManyUnordered<D>>) -> Set<ObjectPublisher<D>> {
|
||||
|
||||
get {
|
||||
|
||||
let key = String(keyPath: member)
|
||||
return self.values[key] as! Set<D.ObjectID>
|
||||
let context = self.context
|
||||
let ids = self.values[key] as! Set<D.ObjectID>
|
||||
return Set(ids.map(context.objectPublisher(objectID:)))
|
||||
}
|
||||
set {
|
||||
|
||||
let key = String(keyPath: member)
|
||||
self.values[key] = newValue
|
||||
self.values[key] = Set(newValue.map({ $0.objectID() }))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user