mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-03-29 13:51:48 +02: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
|
// MARK: Private
|
||||||
|
|||||||
@@ -195,6 +195,7 @@ public final class ObjectPublisher<O: DynamicObject>: ObjectRepresentation, Hash
|
|||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
|
|
||||||
|
self.context.objectsDidChangeObserver(remove: self)
|
||||||
self.observers.removeAllObjects()
|
self.observers.removeAllObjects()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,30 +222,36 @@ public final class ObjectPublisher<O: DynamicObject>: ObjectRepresentation, Hash
|
|||||||
|
|
||||||
self.rawObjectWillChange = nil
|
self.rawObjectWillChange = nil
|
||||||
}
|
}
|
||||||
self.$lazySnapshot.initialize({ initializer(objectID, context) })
|
self.$lazySnapshot.initialize { [weak self] in
|
||||||
|
|
||||||
context.objectsDidChangeObserver(for: self).addObserver(self) { [weak self] (updatedIDs, deletedIDs) in
|
|
||||||
|
|
||||||
guard let self = self else {
|
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()
|
return
|
||||||
self.$lazySnapshot.reset({ nil })
|
}
|
||||||
self.didChange()
|
if deletedIDs.contains(objectID) {
|
||||||
self.notifyObservers()
|
|
||||||
}
|
self.object = nil
|
||||||
else if updatedIDs.contains(objectID) {
|
|
||||||
|
self.willChange()
|
||||||
self.willChange()
|
self.$lazySnapshot.reset({ nil })
|
||||||
self.$lazySnapshot.reset({ initializer(objectID, context) })
|
self.didChange()
|
||||||
self.didChange()
|
self.notifyObservers()
|
||||||
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
|
return nil
|
||||||
}
|
}
|
||||||
self.id = objectID
|
self.id = objectID
|
||||||
|
self.context = context
|
||||||
self.values = values
|
self.values = values
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,6 +115,7 @@ public struct ObjectSnapshot<O: DynamicObject>: ObjectRepresentation, Hashable {
|
|||||||
// MARK: Private
|
// MARK: Private
|
||||||
|
|
||||||
private let id: O.ObjectID
|
private let id: O.ObjectID
|
||||||
|
private let context: NSManagedObjectContext
|
||||||
private var values: [String: Any]
|
private var values: [String: Any]
|
||||||
|
|
||||||
private var valuesRef: NSDictionary {
|
private var valuesRef: NSDictionary {
|
||||||
@@ -214,51 +216,59 @@ extension ObjectSnapshot where O: CoreStoreObject {
|
|||||||
/**
|
/**
|
||||||
Returns the value for the property identified by a given key.
|
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 {
|
get {
|
||||||
|
|
||||||
let key = String(keyPath: member)
|
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 {
|
set {
|
||||||
|
|
||||||
let key = String(keyPath: member)
|
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.
|
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 {
|
get {
|
||||||
|
|
||||||
let key = String(keyPath: member)
|
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 {
|
set {
|
||||||
|
|
||||||
let key = String(keyPath: member)
|
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.
|
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 {
|
get {
|
||||||
|
|
||||||
let key = String(keyPath: member)
|
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 {
|
set {
|
||||||
|
|
||||||
let key = String(keyPath: member)
|
let key = String(keyPath: member)
|
||||||
self.values[key] = newValue
|
self.values[key] = Set(newValue.map({ $0.objectID() }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user