mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-01-16 14:06:53 +01:00
Fixed ListMonitor bug for CoreStoreObjects where ListObservers don't get update notifications
This commit is contained in:
@@ -704,13 +704,13 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
|
||||
guard let `self` = self,
|
||||
let userInfo = note.userInfo,
|
||||
let object = userInfo[String(describing: NSManagedObject.self)] as? ObjectType else {
|
||||
let rawObject = userInfo[String(describing: NSManagedObject.self)] as? NSManagedObject else {
|
||||
|
||||
return
|
||||
}
|
||||
callback(
|
||||
self,
|
||||
object,
|
||||
ObjectType.cs_fromRaw(object: rawObject),
|
||||
userInfo[String(describing: IndexPath.self)] as? IndexPath,
|
||||
userInfo["\(String(describing: IndexPath.self)).New"] as? IndexPath
|
||||
)
|
||||
|
||||
@@ -160,10 +160,9 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
object,
|
||||
{ () -> V in
|
||||
|
||||
return object.rawObject!.getValue(
|
||||
forKvcKey: self.keyPath,
|
||||
didGetValue: { V.cs_fromImportableNativeType($0 as! V.ImportableNativeType)! }
|
||||
)
|
||||
return V.cs_fromImportableNativeType(
|
||||
object.rawObject!.value(forKey: self.keyPath)! as! V.ImportableNativeType
|
||||
)!
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -181,7 +180,7 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
self.isTransient || object.rawObject!.isEditableInContext() == true,
|
||||
object.rawObject!.isEditableInContext() == true,
|
||||
"Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction."
|
||||
)
|
||||
let customSetter = (self.customSetter ?? { $1($2) })
|
||||
@@ -190,9 +189,8 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
{ (newValue: V) -> Void in
|
||||
|
||||
object.rawObject!.setValue(
|
||||
newValue,
|
||||
forKvcKey: self.keyPath,
|
||||
willSetValue: { $0.cs_toImportableNativeType() }
|
||||
newValue.cs_toImportableNativeType(),
|
||||
forKey: self.keyPath
|
||||
)
|
||||
},
|
||||
newValue
|
||||
@@ -201,6 +199,52 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The primitive value. Compared to `value`, `primitiveValue` bypasses all notification mechanisms. This is typically only used for setting values for transient properties.
|
||||
*/
|
||||
public var primitiveValue: V {
|
||||
|
||||
get {
|
||||
|
||||
CoreStore.assert(
|
||||
self.parentObject != nil,
|
||||
"Attempted to access primitive values from a \(cs_typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types."
|
||||
)
|
||||
return withExtendedLifetime(self.parentObject! as! O) { (object: O) in
|
||||
|
||||
CoreStore.assert(
|
||||
object.rawObject!.isRunningInAllowedQueue() == true,
|
||||
"Attempted to access \(cs_typeName(O.self))'s primitive value outside it's designated queue."
|
||||
)
|
||||
return V.cs_fromImportableNativeType(
|
||||
object.rawObject!.primitiveValue(forKey: self.keyPath)! as! V.ImportableNativeType
|
||||
)!
|
||||
}
|
||||
}
|
||||
set {
|
||||
|
||||
CoreStore.assert(
|
||||
self.parentObject != nil,
|
||||
"Attempted to access primitive values from a \(cs_typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types."
|
||||
)
|
||||
return withExtendedLifetime(self.parentObject! as! O) { (object: O) in
|
||||
|
||||
CoreStore.assert(
|
||||
object.rawObject!.isRunningInAllowedQueue() == true,
|
||||
"Attempted to access \(cs_typeName(O.self))'s primitive value outside it's designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
self.isTransient || object.rawObject!.isEditableInContext() == true,
|
||||
"Attempted to update a \(cs_typeName(O.self))'s primitive value from outside a transaction."
|
||||
)
|
||||
object.rawObject!.setPrimitiveValue(
|
||||
newValue.cs_toImportableNativeType(),
|
||||
forKey: self.keyPath
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: AttributeProtocol
|
||||
|
||||
@@ -363,10 +407,8 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
object,
|
||||
{ () -> V? in
|
||||
|
||||
return object.rawObject!.getValue(
|
||||
forKvcKey: self.keyPath,
|
||||
didGetValue: { ($0 as! V.ImportableNativeType?).flatMap(V.cs_fromImportableNativeType) }
|
||||
)
|
||||
return (object.rawObject!.value(forKey: self.keyPath) as! V.ImportableNativeType?)
|
||||
.flatMap(V.cs_fromImportableNativeType)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -384,7 +426,7 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
self.isTransient || object.rawObject!.isEditableInContext() == true,
|
||||
object.rawObject!.isEditableInContext() == true,
|
||||
"Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction."
|
||||
)
|
||||
let customSetter = (self.customSetter ?? { $1($2) })
|
||||
@@ -393,9 +435,8 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
{ (newValue: V?) -> Void in
|
||||
|
||||
object.rawObject!.setValue(
|
||||
newValue,
|
||||
forKvcKey: self.keyPath,
|
||||
willSetValue: { $0?.cs_toImportableNativeType() }
|
||||
newValue?.cs_toImportableNativeType(),
|
||||
forKey: self.keyPath
|
||||
)
|
||||
},
|
||||
newValue
|
||||
@@ -404,6 +445,51 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The primitive value. Compared to `value`, `primitiveValue` bypasses all notification mechanisms. This is typically only used for setting values for transient properties.
|
||||
*/
|
||||
public var primitiveValue: V? {
|
||||
|
||||
get {
|
||||
|
||||
CoreStore.assert(
|
||||
self.parentObject != nil,
|
||||
"Attempted to access primitive values from a \(cs_typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types."
|
||||
)
|
||||
return withExtendedLifetime(self.parentObject! as! O) { (object: O) in
|
||||
|
||||
CoreStore.assert(
|
||||
object.rawObject!.isRunningInAllowedQueue() == true,
|
||||
"Attempted to access \(cs_typeName(O.self))'s primitive value outside it's designated queue."
|
||||
)
|
||||
return (object.rawObject!.primitiveValue(forKey: self.keyPath) as! V.ImportableNativeType?)
|
||||
.flatMap(V.cs_fromImportableNativeType)
|
||||
}
|
||||
}
|
||||
set {
|
||||
|
||||
CoreStore.assert(
|
||||
self.parentObject != nil,
|
||||
"Attempted to access primitive values from a \(cs_typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types."
|
||||
)
|
||||
return withExtendedLifetime(self.parentObject! as! O) { (object: O) in
|
||||
|
||||
CoreStore.assert(
|
||||
object.rawObject!.isRunningInAllowedQueue() == true,
|
||||
"Attempted to access \(cs_typeName(O.self))'s primitive value outside it's designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
self.isTransient || object.rawObject!.isEditableInContext() == true,
|
||||
"Attempted to update a \(cs_typeName(O.self))'s primitive value from outside a transaction."
|
||||
)
|
||||
object.rawObject!.setPrimitiveValue(
|
||||
newValue?.cs_toImportableNativeType(),
|
||||
forKey: self.keyPath
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: AttributeProtocol
|
||||
|
||||
@@ -621,10 +707,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
object,
|
||||
{ () -> V in
|
||||
|
||||
return object.rawObject!.getValue(
|
||||
forKvcKey: self.keyPath,
|
||||
didGetValue: { $0 as! V }
|
||||
)
|
||||
return object.rawObject!.value(forKey: self.keyPath)! as! V
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -642,7 +725,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
self.isTransient || object.rawObject!.isEditableInContext() == true,
|
||||
object.rawObject!.isEditableInContext() == true,
|
||||
"Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction."
|
||||
)
|
||||
let customSetter = (self.customSetter ?? { $1($2) })
|
||||
@@ -652,7 +735,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
|
||||
object.rawObject!.setValue(
|
||||
newValue,
|
||||
forKvcKey: self.keyPath
|
||||
forKey: self.keyPath
|
||||
)
|
||||
},
|
||||
newValue
|
||||
@@ -661,6 +744,50 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The primitive value. Compared to `value`, `primitiveValue` bypasses all notification mechanisms. This is typically only used for setting values for transient properties.
|
||||
*/
|
||||
public var primitiveValue: V {
|
||||
|
||||
get {
|
||||
|
||||
CoreStore.assert(
|
||||
self.parentObject != nil,
|
||||
"Attempted to access primitive values from a \(cs_typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types."
|
||||
)
|
||||
return withExtendedLifetime(self.parentObject! as! O) { (object: O) in
|
||||
|
||||
CoreStore.assert(
|
||||
object.rawObject!.isRunningInAllowedQueue() == true,
|
||||
"Attempted to access \(cs_typeName(O.self))'s primitive value outside it's designated queue."
|
||||
)
|
||||
return object.rawObject!.primitiveValue(forKey: self.keyPath)! as! V
|
||||
}
|
||||
}
|
||||
set {
|
||||
|
||||
CoreStore.assert(
|
||||
self.parentObject != nil,
|
||||
"Attempted to access primitive values from a \(cs_typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types."
|
||||
)
|
||||
return withExtendedLifetime(self.parentObject! as! O) { (object: O) in
|
||||
|
||||
CoreStore.assert(
|
||||
object.rawObject!.isRunningInAllowedQueue() == true,
|
||||
"Attempted to access \(cs_typeName(O.self))'s primitive value outside it's designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
self.isTransient || object.rawObject!.isEditableInContext() == true,
|
||||
"Attempted to update a \(cs_typeName(O.self))'s primitive value from outside a transaction."
|
||||
)
|
||||
object.rawObject!.setPrimitiveValue(
|
||||
newValue,
|
||||
forKey: self.keyPath
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: AttributeProtocol
|
||||
|
||||
@@ -807,10 +934,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
object,
|
||||
{ () -> V? in
|
||||
|
||||
return object.rawObject!.getValue(
|
||||
forKvcKey: self.keyPath,
|
||||
didGetValue: { $0 as! V? }
|
||||
)
|
||||
object.rawObject!.value(forKey: self.keyPath) as! V?
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -828,7 +952,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
self.isTransient || object.rawObject!.isEditableInContext() == true,
|
||||
object.rawObject!.isEditableInContext() == true,
|
||||
"Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction."
|
||||
)
|
||||
let customSetter = (self.customSetter ?? { $1($2) })
|
||||
@@ -838,7 +962,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
|
||||
object.rawObject!.setValue(
|
||||
newValue,
|
||||
forKvcKey: self.keyPath
|
||||
forKey: self.keyPath
|
||||
)
|
||||
},
|
||||
newValue
|
||||
@@ -847,6 +971,50 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The primitive value. Compared to `value`, `primitiveValue` bypasses all notification mechanisms. This is typically only used for setting values for transient properties.
|
||||
*/
|
||||
public var primitiveValue: V? {
|
||||
|
||||
get {
|
||||
|
||||
CoreStore.assert(
|
||||
self.parentObject != nil,
|
||||
"Attempted to access primitive values from a \(cs_typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types."
|
||||
)
|
||||
return withExtendedLifetime(self.parentObject! as! O) { (object: O) in
|
||||
|
||||
CoreStore.assert(
|
||||
object.rawObject!.isRunningInAllowedQueue() == true,
|
||||
"Attempted to access \(cs_typeName(O.self))'s primitive value outside it's designated queue."
|
||||
)
|
||||
return object.rawObject!.primitiveValue(forKey: self.keyPath) as! V?
|
||||
}
|
||||
}
|
||||
set {
|
||||
|
||||
CoreStore.assert(
|
||||
self.parentObject != nil,
|
||||
"Attempted to access primitive values from a \(cs_typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types."
|
||||
)
|
||||
return withExtendedLifetime(self.parentObject! as! O) { (object: O) in
|
||||
|
||||
CoreStore.assert(
|
||||
object.rawObject!.isRunningInAllowedQueue() == true,
|
||||
"Attempted to access \(cs_typeName(O.self))'s primitive value outside it's designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
self.isTransient || object.rawObject!.isEditableInContext() == true,
|
||||
"Attempted to update a \(cs_typeName(O.self))'s primitive value from outside a transaction."
|
||||
)
|
||||
object.rawObject!.setPrimitiveValue(
|
||||
newValue,
|
||||
forKey: self.keyPath
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: AttributeProtocol
|
||||
|
||||
|
||||
Reference in New Issue
Block a user