mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-03-25 10:51:59 +01:00
bypass thread checks depending on location of Field call
This commit is contained in:
@@ -172,10 +172,17 @@ extension CoreStoreObject {
|
|||||||
switch child.value {
|
switch child.value {
|
||||||
|
|
||||||
case let property as FieldAttributeProtocol:
|
case let property as FieldAttributeProtocol:
|
||||||
attributes[property.keyPath] = type(of: property).read(field: property, for: object.rawObject!)
|
attributes[property.keyPath] = type(of: property).read(
|
||||||
|
field: property,
|
||||||
|
for: object.rawObject!,
|
||||||
|
bypassThreadCheck: false
|
||||||
|
)
|
||||||
|
|
||||||
case let property as FieldRelationshipProtocol:
|
case let property as FieldRelationshipProtocol:
|
||||||
attributes[property.keyPath] = type(of: property).valueForSnapshot(field: property, for: object.rawObject!)
|
attributes[property.keyPath] = type(of: property).valueForSnapshot(
|
||||||
|
field: property,
|
||||||
|
for: object.rawObject!
|
||||||
|
)
|
||||||
|
|
||||||
case let property as AttributeProtocol:
|
case let property as AttributeProtocol:
|
||||||
attributes[property.keyPath] = property.valueForSnapshot
|
attributes[property.keyPath] = property.valueForSnapshot
|
||||||
@@ -212,7 +219,11 @@ extension CoreStoreObject {
|
|||||||
switch property {
|
switch property {
|
||||||
|
|
||||||
case let property as FieldAttributeProtocol:
|
case let property as FieldAttributeProtocol:
|
||||||
values[property.keyPath] = type(of: property).read(field: property, for: rawObject)
|
values[property.keyPath] = type(of: property).read(
|
||||||
|
field: property,
|
||||||
|
for: rawObject,
|
||||||
|
bypassThreadCheck: false
|
||||||
|
)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ extension FieldContainer {
|
|||||||
- parameter keyPath: the permanent attribute name for this property.
|
- parameter keyPath: the permanent attribute name for this property.
|
||||||
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
|
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
|
||||||
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
|
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
|
||||||
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.primitiveValue(for:)` instead of `ObjectProxy<O>.value(for:)`, which would unintentionally execute the same closure again recursively.
|
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
|
||||||
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
|
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
|
||||||
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
|
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
|
||||||
*/
|
*/
|
||||||
@@ -161,7 +161,7 @@ extension FieldContainer {
|
|||||||
instance.rawObject != nil,
|
instance.rawObject != nil,
|
||||||
"Attempted to access values from a \(Internals.typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types."
|
"Attempted to access values from a \(Internals.typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types."
|
||||||
)
|
)
|
||||||
return self.read(field: instance[keyPath: storageKeyPath], for: instance.rawObject!) as! V
|
return self.read(field: instance[keyPath: storageKeyPath], for: instance.rawObject!, bypassThreadCheck: false) as! V
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
|
|
||||||
@@ -200,10 +200,10 @@ extension FieldContainer {
|
|||||||
|
|
||||||
// MARK: FieldProtocol
|
// MARK: FieldProtocol
|
||||||
|
|
||||||
internal static func read(field: FieldProtocol, for rawObject: CoreStoreManagedObject) -> Any? {
|
internal static func read(field: FieldProtocol, for rawObject: CoreStoreManagedObject, bypassThreadCheck: Bool) -> Any? {
|
||||||
|
|
||||||
Internals.assert(
|
Internals.assert(
|
||||||
rawObject.isRunningInAllowedQueue() == true,
|
bypassThreadCheck || rawObject.isRunningInAllowedQueue() == true,
|
||||||
"Attempted to access \(Internals.typeName(O.self))'s value outside it's designated queue."
|
"Attempted to access \(Internals.typeName(O.self))'s value outside it's designated queue."
|
||||||
)
|
)
|
||||||
let field = field as! Self
|
let field = field as! Self
|
||||||
@@ -397,7 +397,7 @@ extension FieldContainer.Coded where V: FieldOptionalType {
|
|||||||
- parameter keyPath: the permanent attribute name for this property.
|
- parameter keyPath: the permanent attribute name for this property.
|
||||||
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
|
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
|
||||||
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
|
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
|
||||||
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.primitiveValue(for:)` instead of `ObjectProxy<O>.value(for:)`, which would unintentionally execute the same closure again recursively.
|
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
|
||||||
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
|
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
|
||||||
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
|
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
|
||||||
*/
|
*/
|
||||||
@@ -485,7 +485,7 @@ extension FieldContainer.Coded where V: DefaultNSSecureCodable {
|
|||||||
- parameter keyPath: the permanent attribute name for this property.
|
- parameter keyPath: the permanent attribute name for this property.
|
||||||
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
|
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
|
||||||
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
|
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
|
||||||
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.primitiveValue(for:)` instead of `ObjectProxy<O>.value(for:)`, which would unintentionally execute the same closure again recursively.
|
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
|
||||||
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
|
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
|
||||||
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
|
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ extension FieldContainer {
|
|||||||
instance.rawObject != nil,
|
instance.rawObject != nil,
|
||||||
"Attempted to access values from a \(Internals.typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types."
|
"Attempted to access values from a \(Internals.typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types."
|
||||||
)
|
)
|
||||||
return self.read(field: instance[keyPath: storageKeyPath], for: instance.rawObject!) as! V
|
return self.read(field: instance[keyPath: storageKeyPath], for: instance.rawObject!, bypassThreadCheck: false) as! V
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
|
|
||||||
@@ -138,10 +138,10 @@ extension FieldContainer {
|
|||||||
|
|
||||||
// MARK: FieldProtocol
|
// MARK: FieldProtocol
|
||||||
|
|
||||||
internal static func read(field: FieldProtocol, for rawObject: CoreStoreManagedObject) -> Any? {
|
internal static func read(field: FieldProtocol, for rawObject: CoreStoreManagedObject, bypassThreadCheck: Bool) -> Any? {
|
||||||
|
|
||||||
Internals.assert(
|
Internals.assert(
|
||||||
rawObject.isRunningInAllowedQueue() == true,
|
bypassThreadCheck || rawObject.isRunningInAllowedQueue() == true,
|
||||||
"Attempted to access \(Internals.typeName(O.self))'s value outside it's designated queue."
|
"Attempted to access \(Internals.typeName(O.self))'s value outside it's designated queue."
|
||||||
)
|
)
|
||||||
let field = field as! Self
|
let field = field as! Self
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ extension FieldContainer {
|
|||||||
- parameter keyPath: the permanent attribute name for this property.
|
- parameter keyPath: the permanent attribute name for this property.
|
||||||
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
|
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
|
||||||
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
|
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
|
||||||
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.primitiveValue(for:)` instead of `ObjectProxy<O>.value(for:)`, which would unintentionally execute the same closure again recursively.
|
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
|
||||||
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
|
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
|
||||||
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
|
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
|
||||||
*/
|
*/
|
||||||
@@ -128,7 +128,7 @@ extension FieldContainer {
|
|||||||
instance.rawObject != nil,
|
instance.rawObject != nil,
|
||||||
"Attempted to access values from a \(Internals.typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types."
|
"Attempted to access values from a \(Internals.typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types."
|
||||||
)
|
)
|
||||||
return self.read(field: instance[keyPath: storageKeyPath], for: instance.rawObject!) as! V
|
return self.read(field: instance[keyPath: storageKeyPath], for: instance.rawObject!, bypassThreadCheck: false) as! V
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
|
|
||||||
@@ -167,10 +167,10 @@ extension FieldContainer {
|
|||||||
|
|
||||||
// MARK: FieldProtocol
|
// MARK: FieldProtocol
|
||||||
|
|
||||||
internal static func read(field: FieldProtocol, for rawObject: CoreStoreManagedObject) -> Any? {
|
internal static func read(field: FieldProtocol, for rawObject: CoreStoreManagedObject, bypassThreadCheck: Bool) -> Any? {
|
||||||
|
|
||||||
Internals.assert(
|
Internals.assert(
|
||||||
rawObject.isRunningInAllowedQueue() == true,
|
bypassThreadCheck || rawObject.isRunningInAllowedQueue() == true,
|
||||||
"Attempted to access \(Internals.typeName(O.self))'s value outside it's designated queue."
|
"Attempted to access \(Internals.typeName(O.self))'s value outside it's designated queue."
|
||||||
)
|
)
|
||||||
let field = field as! Self
|
let field = field as! Self
|
||||||
@@ -344,7 +344,7 @@ extension FieldContainer.Stored where V: FieldOptionalType {
|
|||||||
- parameter keyPath: the permanent attribute name for this property.
|
- parameter keyPath: the permanent attribute name for this property.
|
||||||
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
|
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
|
||||||
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
|
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
|
||||||
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.primitiveValue(for:)` instead of `ObjectProxy<O>.value(for:)`, which would unintentionally execute the same closure again recursively.
|
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
|
||||||
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
|
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
|
||||||
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
|
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ extension FieldContainer {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
- parameter keyPath: the permanent attribute name for this property.
|
- parameter keyPath: the permanent attribute name for this property.
|
||||||
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.primitiveValue(for:)` instead of `ObjectProxy<O>.value(for:)`, which would unintentionally execute the same closure again recursively.
|
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
|
||||||
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
|
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
|
||||||
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
|
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
|
||||||
*/
|
*/
|
||||||
@@ -139,7 +139,7 @@ extension FieldContainer {
|
|||||||
instance.rawObject != nil,
|
instance.rawObject != nil,
|
||||||
"Attempted to access values from a \(Internals.typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types."
|
"Attempted to access values from a \(Internals.typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types."
|
||||||
)
|
)
|
||||||
return self.read(field: instance[keyPath: storageKeyPath], for: instance.rawObject!) as! V
|
return self.read(field: instance[keyPath: storageKeyPath], for: instance.rawObject!, bypassThreadCheck: false) as! V
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
|
|
||||||
@@ -178,10 +178,10 @@ extension FieldContainer {
|
|||||||
|
|
||||||
// MARK: FieldProtocol
|
// MARK: FieldProtocol
|
||||||
|
|
||||||
internal static func read(field: FieldProtocol, for rawObject: CoreStoreManagedObject) -> Any? {
|
internal static func read(field: FieldProtocol, for rawObject: CoreStoreManagedObject, bypassThreadCheck: Bool) -> Any? {
|
||||||
|
|
||||||
Internals.assert(
|
Internals.assert(
|
||||||
rawObject.isRunningInAllowedQueue() == true,
|
bypassThreadCheck || rawObject.isRunningInAllowedQueue() == true,
|
||||||
"Attempted to access \(Internals.typeName(O.self))'s value outside it's designated queue."
|
"Attempted to access \(Internals.typeName(O.self))'s value outside it's designated queue."
|
||||||
)
|
)
|
||||||
let field = field as! Self
|
let field = field as! Self
|
||||||
|
|||||||
@@ -31,6 +31,6 @@ import CoreData
|
|||||||
|
|
||||||
internal protocol FieldProtocol: PropertyProtocol {
|
internal protocol FieldProtocol: PropertyProtocol {
|
||||||
|
|
||||||
static func read(field: FieldProtocol, for rawObject: CoreStoreManagedObject) -> Any?
|
static func read(field: FieldProtocol, for rawObject: CoreStoreManagedObject, bypassThreadCheck: Bool) -> Any?
|
||||||
static func modify(field: FieldProtocol, for rawObject: CoreStoreManagedObject, newValue: Any?)
|
static func modify(field: FieldProtocol, for rawObject: CoreStoreManagedObject, newValue: Any?)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,7 +133,11 @@ public struct ObjectProxy<O: CoreStoreObject> {
|
|||||||
let keyPathString = field.keyPath
|
let keyPathString = field.keyPath
|
||||||
self.getValue = {
|
self.getValue = {
|
||||||
|
|
||||||
return type(of: field).read(field: field, for: rawObject) as! V
|
return type(of: field).read(
|
||||||
|
field: field,
|
||||||
|
for: rawObject,
|
||||||
|
bypassThreadCheck: true // May be called from NSError logs
|
||||||
|
) as! V
|
||||||
}
|
}
|
||||||
self.setValue = {
|
self.setValue = {
|
||||||
|
|
||||||
@@ -159,7 +163,11 @@ public struct ObjectProxy<O: CoreStoreObject> {
|
|||||||
let keyPathString = field.keyPath
|
let keyPathString = field.keyPath
|
||||||
self.getValue = {
|
self.getValue = {
|
||||||
|
|
||||||
return type(of: field).read(field: field, for: rawObject) as! V
|
return type(of: field).read(
|
||||||
|
field: field,
|
||||||
|
for: rawObject,
|
||||||
|
bypassThreadCheck: true // May be called from NSError logs
|
||||||
|
) as! V
|
||||||
}
|
}
|
||||||
self.setValue = {
|
self.setValue = {
|
||||||
|
|
||||||
@@ -192,7 +200,11 @@ public struct ObjectProxy<O: CoreStoreObject> {
|
|||||||
let keyPathString = field.keyPath
|
let keyPathString = field.keyPath
|
||||||
self.getValue = {
|
self.getValue = {
|
||||||
|
|
||||||
return type(of: field).read(field: field, for: rawObject) as! V
|
return type(of: field).read(
|
||||||
|
field: field,
|
||||||
|
for: rawObject,
|
||||||
|
bypassThreadCheck: true // May be called from NSError logs
|
||||||
|
) as! V
|
||||||
}
|
}
|
||||||
self.setValue = {
|
self.setValue = {
|
||||||
|
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ extension ObjectPublisher where O: CoreStoreObject {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
let field = object[keyPath: member]
|
let field = object[keyPath: member]
|
||||||
return type(of: field).read(field: field, for: rawObject) as! V?
|
return type(of: field).read(field: field, for: rawObject, bypassThreadCheck: false) as! V?
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -396,7 +396,7 @@ extension ObjectPublisher where O: CoreStoreObject {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
let field = object[keyPath: member]
|
let field = object[keyPath: member]
|
||||||
return type(of: field).read(field: field, for: rawObject) as! V?
|
return type(of: field).read(field: field, for: rawObject, bypassThreadCheck: false) as! V?
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -412,7 +412,7 @@ extension ObjectPublisher where O: CoreStoreObject {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
let field = object[keyPath: member]
|
let field = object[keyPath: member]
|
||||||
return type(of: field).read(field: field, for: rawObject) as! V?
|
return type(of: field).read(field: field, for: rawObject, bypassThreadCheck: false) as! V?
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -428,7 +428,7 @@ extension ObjectPublisher where O: CoreStoreObject {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
let field = object[keyPath: member]
|
let field = object[keyPath: member]
|
||||||
guard let value = type(of: field).read(field: field, for: rawObject) as! V? else {
|
guard let value = type(of: field).read(field: field, for: rawObject, bypassThreadCheck: false) as! V? else {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user