mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-01-16 14:06:53 +01:00
WIP: new PartialObject to act as faster KVC wrappers when implementing custom getters and setters for CoreStoreObject
This commit is contained in:
@@ -242,6 +242,10 @@
|
||||
B53B27601EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
|
||||
B53B27611EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
|
||||
B53B27621EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
|
||||
B53CA9A21EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
|
||||
B53CA9A31EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
|
||||
B53CA9A41EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
|
||||
B53CA9A51EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
|
||||
B53FB9FE1CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
||||
B53FBA001CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
||||
B53FBA011CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
||||
@@ -757,6 +761,7 @@
|
||||
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DispatchQueue+CoreStore.swift"; sourceTree = "<group>"; };
|
||||
B538BA701D15B3E30003A766 /* CoreStoreBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreStoreBridge.m; sourceTree = "<group>"; };
|
||||
B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreManagedObject.swift; sourceTree = "<group>"; };
|
||||
B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PartialObject.swift; sourceTree = "<group>"; };
|
||||
B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSMigrationResult.swift; sourceTree = "<group>"; };
|
||||
B53FBA031CAB300C00F0D40A /* CSMigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSMigrationType.swift; sourceTree = "<group>"; };
|
||||
B53FBA0A1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CSCoreStore+Migrating.swift"; sourceTree = "<group>"; };
|
||||
@@ -1229,6 +1234,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */,
|
||||
B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */,
|
||||
B52F74391E9B8724005F3DAC /* Dynamic Schema */,
|
||||
B5D339DC1E9489C700C880DE /* DynamicObject.swift */,
|
||||
B52F742E1E9B50D0005F3DAC /* SchemaHistory.swift */,
|
||||
@@ -1826,6 +1832,7 @@
|
||||
B5FAD6AE1B518DCB00714891 /* CoreStore+Migration.swift in Sources */,
|
||||
B5E84EE71AFF84610064E85B /* CoreStore+Logging.swift in Sources */,
|
||||
B546F9731C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
||||
B53CA9A21EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||
B56007111B3F6BD500A9A8F9 /* Into.swift in Sources */,
|
||||
B5E84F111AFF847B0064E85B /* Select.swift in Sources */,
|
||||
B51260931E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||
@@ -2011,6 +2018,7 @@
|
||||
82BA18A31C4BBD2200A0916E /* DataStack.swift in Sources */,
|
||||
82BA18C81C4BBD5900A0916E /* MigrationChain.swift in Sources */,
|
||||
B546F9741C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
||||
B53CA9A31EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||
82BA18B11C4BBD3100A0916E /* SaveResult.swift in Sources */,
|
||||
82BA18DD1C4BBE1400A0916E /* NSFetchedResultsController+Convenience.swift in Sources */,
|
||||
B51260941E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||
@@ -2196,6 +2204,7 @@
|
||||
B52DD1961BE1F92500949AFE /* DataStack.swift in Sources */,
|
||||
B5ECDBFD1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
|
||||
B52DD1BD1BE1F94300949AFE /* NSManagedObject+Convenience.swift in Sources */,
|
||||
B53CA9A51EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||
B52DD1AD1BE1F93900949AFE /* Where.swift in Sources */,
|
||||
B53FBA1C1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
|
||||
B51260961E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||
@@ -2381,6 +2390,7 @@
|
||||
B56321A81BD65219006C9394 /* NSManagedObject+Convenience.swift in Sources */,
|
||||
B546F9751C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
||||
B56321981BD65216006C9394 /* Where.swift in Sources */,
|
||||
B53CA9A41EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||
B5202CFD1C046E8400DED140 /* NSFetchedResultsController+Convenience.swift in Sources */,
|
||||
B5FE4DA91C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
||||
B51260951E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||
|
||||
@@ -135,3 +135,23 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - DynamicObject where Self: CoreStoreObject
|
||||
|
||||
public extension DynamicObject where Self: CoreStoreObject {
|
||||
|
||||
public func partialObject() -> PartialObject<Self> {
|
||||
|
||||
CoreStore.assert(
|
||||
!self.isMeta,
|
||||
"Attempted to create a \(cs_typeName(PartialObject<Self>.self)) from a meta object. Meta objects are only used for querying keyPaths and infering types."
|
||||
)
|
||||
return PartialObject<Self>(self.rawObject!)
|
||||
}
|
||||
|
||||
internal static var meta: Self {
|
||||
|
||||
return self.init(asMeta: ())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,14 +155,3 @@ extension CoreStoreObject {
|
||||
return self.rawObject!
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Internal
|
||||
|
||||
internal extension DynamicObject where Self: CoreStoreObject {
|
||||
|
||||
internal static var meta: Self {
|
||||
|
||||
return self.init(asMeta: ())
|
||||
}
|
||||
}
|
||||
|
||||
135
Sources/PartialObject.swift
Normal file
135
Sources/PartialObject.swift
Normal file
@@ -0,0 +1,135 @@
|
||||
//
|
||||
// PartialObject.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2017 John Rommel Estropia
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
import Foundation
|
||||
|
||||
|
||||
// MARK: - PartialObject
|
||||
|
||||
public struct PartialObject<O: CoreStoreObject> {
|
||||
|
||||
public func completeObject() -> O {
|
||||
|
||||
return O.cs_fromRaw(object: self.rawObject)
|
||||
}
|
||||
|
||||
public func value<V: ImportableAttributeType>(for property: (O) -> ValueContainer<O>.Required<V>) -> V {
|
||||
|
||||
return V.cs_fromImportableNativeType(
|
||||
self.rawObject.value(forKey: property(O.meta).keyPath)! as! V.ImportableNativeType
|
||||
)!
|
||||
}
|
||||
|
||||
public func value<V: ImportableAttributeType>(for property: (O) -> ValueContainer<O>.Optional<V>) -> V? {
|
||||
|
||||
return (self.rawObject.value(forKey: property(O.meta).keyPath) as! V.ImportableNativeType?)
|
||||
.flatMap(V.cs_fromImportableNativeType)
|
||||
}
|
||||
|
||||
public func value<V: NSCoding & NSCopying>(for property: (O) -> TransformableContainer<O>.Required<V>) -> V {
|
||||
|
||||
return self.rawObject.value(forKey: property(O.meta).keyPath)! as! V
|
||||
}
|
||||
|
||||
public func value<V: NSCoding & NSCopying>(for property: (O) -> TransformableContainer<O>.Optional<V>) -> V? {
|
||||
|
||||
return self.rawObject.value(forKey: property(O.meta).keyPath) as! V?
|
||||
}
|
||||
|
||||
public func setValue<V: ImportableAttributeType>(_ value: V, for property: (O) -> ValueContainer<O>.Required<V>) {
|
||||
|
||||
self.rawObject.setValue(
|
||||
value.cs_toImportableNativeType(),
|
||||
forKey: property(O.meta).keyPath
|
||||
)
|
||||
}
|
||||
|
||||
public func setValue<V: ImportableAttributeType>(_ value: V?, for property: (O) -> ValueContainer<O>.Optional<V>) {
|
||||
|
||||
self.rawObject.setValue(
|
||||
value?.cs_toImportableNativeType(),
|
||||
forKey: property(O.meta).keyPath
|
||||
)
|
||||
}
|
||||
|
||||
public func setValue<V: NSCoding & NSCopying>(_ value: V, for property: (O) -> TransformableContainer<O>.Required<V>) {
|
||||
|
||||
self.rawObject.setValue(
|
||||
value,
|
||||
forKey: property(O.meta).keyPath
|
||||
)
|
||||
}
|
||||
|
||||
public func setValue<V: NSCoding & NSCopying>(_ value: V?, for property: (O) -> TransformableContainer<O>.Optional<V>) {
|
||||
|
||||
self.rawObject.setValue(
|
||||
value,
|
||||
forKey: property(O.meta).keyPath
|
||||
)
|
||||
}
|
||||
|
||||
public func setPrimitiveValue<V: ImportableAttributeType>(_ value: V, for property: (O) -> ValueContainer<O>.Required<V>) {
|
||||
|
||||
self.rawObject.setPrimitiveValue(
|
||||
value.cs_toImportableNativeType(),
|
||||
forKey: property(O.meta).keyPath
|
||||
)
|
||||
}
|
||||
|
||||
public func setPrimitiveValue<V: ImportableAttributeType>(_ value: V?, for property: (O) -> ValueContainer<O>.Optional<V>) {
|
||||
|
||||
self.rawObject.setPrimitiveValue(
|
||||
value?.cs_toImportableNativeType(),
|
||||
forKey: property(O.meta).keyPath
|
||||
)
|
||||
}
|
||||
|
||||
public func setPrimitiveValue<V: NSCoding & NSCopying>(_ value: V, for property: (O) -> TransformableContainer<O>.Required<V>) {
|
||||
|
||||
self.rawObject.setPrimitiveValue(
|
||||
value,
|
||||
forKey: property(O.meta).keyPath
|
||||
)
|
||||
}
|
||||
|
||||
public func setPrimitiveValue<V: NSCoding & NSCopying>(_ value: V?, for property: (O) -> TransformableContainer<O>.Optional<V>) {
|
||||
|
||||
self.rawObject.setPrimitiveValue(
|
||||
value,
|
||||
forKey: property(O.meta).keyPath
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal let rawObject: NSManagedObject
|
||||
|
||||
internal init(_ rawObject: NSManagedObject) {
|
||||
|
||||
self.rawObject = rawObject
|
||||
}
|
||||
}
|
||||
@@ -123,8 +123,8 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
isTransient: Bool = false,
|
||||
versionHashModifier: String? = nil,
|
||||
renamingIdentifier: String? = nil,
|
||||
customGetter: ((_ `self`: O, _ getValue: () -> V) -> V)? = nil,
|
||||
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V) -> Void, _ originalNewValue: V) -> Void)? = nil,
|
||||
customGetter: ((_ partialObject: PartialObject<O>) -> V)? = nil,
|
||||
customSetter: ((_ partialObject: PartialObject<O>, _ newValue: V) -> Void)? = nil,
|
||||
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
|
||||
|
||||
self.keyPath = keyPath
|
||||
@@ -155,16 +155,13 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
object.rawObject!.isRunningInAllowedQueue() == true,
|
||||
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
|
||||
)
|
||||
let customGetter = (self.customGetter ?? { $1() })
|
||||
return customGetter(
|
||||
object,
|
||||
{ () -> V in
|
||||
|
||||
return V.cs_fromImportableNativeType(
|
||||
object.rawObject!.value(forKey: self.keyPath)! as! V.ImportableNativeType
|
||||
)!
|
||||
}
|
||||
)
|
||||
if let customGetter = self.customGetter {
|
||||
|
||||
return customGetter(PartialObject<O>(object.rawObject!))
|
||||
}
|
||||
return V.cs_fromImportableNativeType(
|
||||
object.rawObject!.value(forKey: self.keyPath)! as! V.ImportableNativeType
|
||||
)!
|
||||
}
|
||||
}
|
||||
set {
|
||||
@@ -183,17 +180,13 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
object.rawObject!.isEditableInContext() == true,
|
||||
"Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction."
|
||||
)
|
||||
let customSetter = (self.customSetter ?? { $1($2) })
|
||||
customSetter(
|
||||
object,
|
||||
{ (newValue: V) -> Void in
|
||||
|
||||
object.rawObject!.setValue(
|
||||
newValue.cs_toImportableNativeType(),
|
||||
forKey: self.keyPath
|
||||
)
|
||||
},
|
||||
newValue
|
||||
if let customSetter = self.customSetter {
|
||||
|
||||
return customSetter(PartialObject<O>(object.rawObject!), newValue)
|
||||
}
|
||||
return object.rawObject!.setValue(
|
||||
newValue.cs_toImportableNativeType(),
|
||||
forKey: self.keyPath
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -274,15 +267,12 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
return { (_ id: Any) -> Any? in
|
||||
|
||||
let rawObject = id as! CoreStoreManagedObject
|
||||
let value = customGetter(
|
||||
O.cs_fromRaw(object: rawObject),
|
||||
{
|
||||
rawObject.getValue(
|
||||
forKvcKey: keyPath,
|
||||
didGetValue: { V.cs_fromImportableNativeType($0 as! V.ImportableNativeType!)! }
|
||||
)
|
||||
}
|
||||
)
|
||||
rawObject.willAccessValue(forKey: keyPath)
|
||||
defer {
|
||||
|
||||
rawObject.didAccessValue(forKey: keyPath)
|
||||
}
|
||||
let value = customGetter(PartialObject<O>(rawObject))
|
||||
return value.cs_toImportableNativeType()
|
||||
}
|
||||
}
|
||||
@@ -297,16 +287,13 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
return { (_ id: Any, _ newValue: Any?) -> Void in
|
||||
|
||||
let rawObject = id as! CoreStoreManagedObject
|
||||
rawObject.willChangeValue(forKey: keyPath)
|
||||
defer {
|
||||
|
||||
rawObject.didChangeValue(forKey: keyPath)
|
||||
}
|
||||
customSetter(
|
||||
O.cs_fromRaw(object: rawObject),
|
||||
{ (userValue: V) -> Void in
|
||||
|
||||
rawObject.setValue(
|
||||
userValue,
|
||||
forKvcKey: keyPath,
|
||||
willSetValue: { $0.cs_toImportableNativeType() }
|
||||
)
|
||||
},
|
||||
PartialObject<O>(rawObject),
|
||||
V.cs_fromImportableNativeType(newValue as! V.ImportableNativeType)!
|
||||
)
|
||||
}
|
||||
@@ -315,8 +302,8 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let customGetter: ((_ `self`: O, _ getValue: () -> V) -> V)?
|
||||
private let customSetter: ((_ `self`: O, _ setValue: (V) -> Void, _ newValue: V) -> Void)?
|
||||
private let customGetter: ((_ partialObject: PartialObject<O>) -> V)?
|
||||
private let customSetter: ((_ partialObject: PartialObject<O>, _ newValue: V) -> Void)?
|
||||
}
|
||||
|
||||
|
||||
@@ -370,8 +357,8 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
isTransient: Bool = false,
|
||||
versionHashModifier: String? = nil,
|
||||
renamingIdentifier: String? = nil,
|
||||
customGetter: ((_ `self`: O, _ getValue: () -> V?) -> V?)? = nil,
|
||||
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V?) -> Void, _ originalNewValue: V?) -> Void)? = nil,
|
||||
customGetter: ((_ partialObject: PartialObject<O>) -> V?)? = nil,
|
||||
customSetter: ((_ partialObject: PartialObject<O>, _ newValue: V?) -> Void)? = nil,
|
||||
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
|
||||
|
||||
self.keyPath = keyPath
|
||||
@@ -402,15 +389,12 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
object.rawObject!.isRunningInAllowedQueue() == true,
|
||||
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
|
||||
)
|
||||
let customGetter = (self.customGetter ?? { $1() })
|
||||
return customGetter(
|
||||
object,
|
||||
{ () -> V? in
|
||||
|
||||
return (object.rawObject!.value(forKey: self.keyPath) as! V.ImportableNativeType?)
|
||||
.flatMap(V.cs_fromImportableNativeType)
|
||||
}
|
||||
)
|
||||
if let customGetter = self.customGetter {
|
||||
|
||||
return customGetter(PartialObject<O>(object.rawObject!))
|
||||
}
|
||||
return (object.rawObject!.value(forKey: self.keyPath) as! V.ImportableNativeType?)
|
||||
.flatMap(V.cs_fromImportableNativeType)
|
||||
}
|
||||
}
|
||||
set {
|
||||
@@ -429,17 +413,13 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
object.rawObject!.isEditableInContext() == true,
|
||||
"Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction."
|
||||
)
|
||||
let customSetter = (self.customSetter ?? { $1($2) })
|
||||
customSetter(
|
||||
object,
|
||||
{ (newValue: V?) -> Void in
|
||||
|
||||
object.rawObject!.setValue(
|
||||
newValue?.cs_toImportableNativeType(),
|
||||
forKey: self.keyPath
|
||||
)
|
||||
},
|
||||
newValue
|
||||
if let customSetter = self.customSetter {
|
||||
|
||||
return customSetter(PartialObject<O>(object.rawObject!), newValue)
|
||||
}
|
||||
object.rawObject!.setValue(
|
||||
newValue?.cs_toImportableNativeType(),
|
||||
forKey: self.keyPath
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -518,15 +498,12 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
return { (_ id: Any) -> Any? in
|
||||
|
||||
let rawObject = id as! CoreStoreManagedObject
|
||||
let value = customGetter(
|
||||
O.cs_fromRaw(object: rawObject),
|
||||
{
|
||||
rawObject.getValue(
|
||||
forKvcKey: keyPath,
|
||||
didGetValue: { ($0 as! V.ImportableNativeType?).flatMap(V.cs_fromImportableNativeType) }
|
||||
)
|
||||
}
|
||||
)
|
||||
rawObject.willAccessValue(forKey: keyPath)
|
||||
defer {
|
||||
|
||||
rawObject.didAccessValue(forKey: keyPath)
|
||||
}
|
||||
let value = customGetter(PartialObject<O>(rawObject))
|
||||
return value?.cs_toImportableNativeType()
|
||||
}
|
||||
}
|
||||
@@ -541,16 +518,13 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
return { (_ id: Any, _ newValue: Any?) -> Void in
|
||||
|
||||
let rawObject = id as! CoreStoreManagedObject
|
||||
rawObject.willChangeValue(forKey: keyPath)
|
||||
defer {
|
||||
|
||||
rawObject.didChangeValue(forKey: keyPath)
|
||||
}
|
||||
customSetter(
|
||||
O.cs_fromRaw(object: rawObject),
|
||||
{ (userValue: V?) -> Void in
|
||||
|
||||
rawObject.setValue(
|
||||
userValue,
|
||||
forKvcKey: keyPath,
|
||||
willSetValue: { $0?.cs_toImportableNativeType() }
|
||||
)
|
||||
},
|
||||
PartialObject<O>(rawObject),
|
||||
(newValue as! V.ImportableNativeType?).flatMap(V.cs_fromImportableNativeType)
|
||||
)
|
||||
}
|
||||
@@ -559,8 +533,8 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let customGetter: ((_ `self`: O, _ getValue: () -> V?) -> V?)?
|
||||
private let customSetter: ((_ `self`: O, _ setValue: (V?) -> Void, _ newValue: V?) -> Void)?
|
||||
private let customGetter: ((_ partialObject: PartialObject<O>) -> V?)?
|
||||
private let customSetter: ((_ partialObject: PartialObject<O>, _ newValue: V?) -> Void)?
|
||||
}
|
||||
}
|
||||
|
||||
@@ -593,7 +567,7 @@ public extension ValueContainer.Required where V: EmptyableAttributeType {
|
||||
isTransient: Bool = false,
|
||||
versionHashModifier: String? = nil,
|
||||
renamingIdentifier: String? = nil,
|
||||
customGetter: ((_ `self`: O, _ getValue: () -> V) -> V)? = nil,
|
||||
customGetter: ((_ `self`: PartialObject<O>, _ getValue: () -> V) -> V)? = nil,
|
||||
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V) -> Void, _ originalNewValue: V) -> Void)? = nil,
|
||||
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
|
||||
|
||||
@@ -670,7 +644,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
isTransient: Bool = false,
|
||||
versionHashModifier: String? = nil,
|
||||
renamingIdentifier: String? = nil,
|
||||
customGetter: ((_ `self`: O, _ getValue: () -> V) -> V)? = nil,
|
||||
customGetter: ((_ `self`: PartialObject<O>, _ getValue: () -> V) -> V)? = nil,
|
||||
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V) -> Void, _ originalNewValue: V) -> Void)? = nil,
|
||||
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
|
||||
|
||||
@@ -704,7 +678,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
)
|
||||
let customGetter = (self.customGetter ?? { $1() })
|
||||
return customGetter(
|
||||
object,
|
||||
PartialObject<O>(object.rawObject!),
|
||||
{ () -> V in
|
||||
|
||||
return object.rawObject!.value(forKey: self.keyPath)! as! V
|
||||
@@ -818,7 +792,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
|
||||
let rawObject = id as! CoreStoreManagedObject
|
||||
return customGetter(
|
||||
O.cs_fromRaw(object: rawObject),
|
||||
PartialObject<O>(rawObject),
|
||||
{ rawObject.getValue(forKvcKey: keyPath) as! V }
|
||||
)
|
||||
}
|
||||
@@ -848,7 +822,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let customGetter: ((_ `self`: O, _ getValue: () -> V) -> V)?
|
||||
private let customGetter: ((_ `self`: PartialObject<O>, _ getValue: () -> V) -> V)?
|
||||
private let customSetter: ((_ `self`: O, _ setValue: (V) -> Void, _ newValue: V) -> Void)?
|
||||
}
|
||||
|
||||
@@ -897,7 +871,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
isTransient: Bool = false,
|
||||
versionHashModifier: String? = nil,
|
||||
renamingIdentifier: String? = nil,
|
||||
customGetter: ((_ `self`: O, _ getValue: () -> V?) -> V?)? = nil,
|
||||
customGetter: ((_ `self`: PartialObject<O>, _ getValue: () -> V?) -> V?)? = nil,
|
||||
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V?) -> Void, _ originalNewValue: V?) -> Void)? = nil,
|
||||
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
|
||||
|
||||
@@ -931,7 +905,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
)
|
||||
let customGetter = (self.customGetter ?? { $1() })
|
||||
return customGetter(
|
||||
object,
|
||||
PartialObject<O>(object.rawObject!),
|
||||
{ () -> V? in
|
||||
|
||||
object.rawObject!.value(forKey: self.keyPath) as! V?
|
||||
@@ -1045,7 +1019,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
|
||||
let rawObject = id as! CoreStoreManagedObject
|
||||
return customGetter(
|
||||
O.cs_fromRaw(object: rawObject),
|
||||
PartialObject<O>(rawObject),
|
||||
{ rawObject.getValue(forKvcKey: keyPath) as! V? }
|
||||
)
|
||||
}
|
||||
@@ -1083,7 +1057,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let customGetter: ((_ `self`: O, _ getValue: () -> V?) -> V?)?
|
||||
private let customGetter: ((_ `self`: PartialObject<O>, _ getValue: () -> V?) -> V?)?
|
||||
private let customSetter: ((_ `self`: O, _ setValue: (V?) -> Void, _ newValue: V?) -> Void)?
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user