Merge branch 'develop' into prototype/Swift_3_2

# Conflicts:
#	Sources/CoreStoreManagedObject.swift
#	Sources/CoreStoreSchema.swift
#	Sources/NSEntityDescription+DynamicModel.swift
#	Sources/Value.swift
This commit is contained in:
John Rommel Estropia
2017-06-11 09:16:34 +09:00
10 changed files with 678 additions and 294 deletions

View File

@@ -118,19 +118,19 @@ public enum ValueContainer<O: CoreStoreObject> {
*/
public init(
_ keyPath: RawKeyPath,
`default`: V,
`default`: @autoclosure @escaping () -> V,
isIndexed: Bool = false,
isTransient: Bool = false,
versionHashModifier: String? = nil,
renamingIdentifier: String? = nil,
customGetter: @escaping (_ `self`: O, _ getValue: () -> V) -> V = { $1() },
customSetter: @escaping (_ `self`: O, _ setValue: (_ finalNewValue: V) -> Void, _ originalNewValue: V) -> Void = { $1($2) },
customGetter: ((_ `self`: O, _ getValue: () -> V) -> V)? = nil,
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V) -> Void, _ originalNewValue: V) -> Void)? = nil,
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
self.keyPath = keyPath
self.isIndexed = isIndexed
self.isTransient = isTransient
self.defaultValue = `default`.cs_toQueryableNativeType()
self.defaultValue = { `default`().cs_toQueryableNativeType() }
self.versionHashModifier = versionHashModifier
self.renamingIdentifier = renamingIdentifier
self.customGetter = customGetter
@@ -145,45 +145,59 @@ public enum ValueContainer<O: CoreStoreObject> {
get {
let object = self.parentObject() as! O
CoreStore.assert(
object.rawObject!.isRunningInAllowedQueue() == true,
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
)
return self.customGetter(
object,
{ () -> V in
return object.rawObject!.getValue(
forKvcKey: self.keyPath,
didGetValue: { V.cs_fromQueryableNativeType($0 as! V.QueryableNativeType)! }
)
}
self.parentObject != nil,
"Attempted to access 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 value outside it's designated queue."
)
let customGetter = (self.customGetter ?? { $1() })
return customGetter(
object,
{ () -> V in
return object.rawObject!.getValue(
forKvcKey: self.keyPath,
didGetValue: { V.cs_fromQueryableNativeType($0 as! V.QueryableNativeType)! }
)
}
)
}
}
set {
let object = self.parentObject() as! O
CoreStore.assert(
object.rawObject!.isRunningInAllowedQueue() == true,
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
)
CoreStore.assert(
object.rawObject!.isEditableInContext() == true,
"Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction."
)
self.customSetter(
object,
{ (newValue: V) -> Void in
object.rawObject!.setValue(
newValue,
forKvcKey: self.keyPath,
willSetValue: { $0.cs_toQueryableNativeType() }
)
},
newValue
self.parentObject != nil,
"Attempted to access 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 value outside it's designated queue."
)
CoreStore.assert(
self.isTransient || 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,
forKvcKey: self.keyPath,
willSetValue: { $0.cs_toQueryableNativeType() }
)
},
newValue
)
}
}
}
@@ -200,21 +214,65 @@ public enum ValueContainer<O: CoreStoreObject> {
internal let isOptional = false
internal let isIndexed: Bool
internal let isTransient: Bool
internal let defaultValue: Any?
internal let versionHashModifier: String?
internal let renamingIdentifier: String?
internal let defaultValue: () -> Any?
internal let affectedByKeyPaths: () -> Set<String>
internal weak var parentObject: CoreStoreObject?
internal var parentObject: () -> CoreStoreObject = {
internal private(set) lazy var getter: CoreStoreManagedObject.CustomGetter? = cs_lazy { [unowned self] in
CoreStore.abort("Attempted to access values from a \(cs_typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types.")
guard let customGetter = self.customGetter else {
return nil
}
let keyPath = self.keyPath
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_fromQueryableNativeType($0 as! V.QueryableNativeType!)! }
)
}
)
return value.cs_toQueryableNativeType()
}
}
internal private(set) lazy var setter: CoreStoreManagedObject.CustomSetter? = cs_lazy { [unowned self] in
guard let customSetter = self.customSetter else {
return nil
}
let keyPath = self.keyPath
return { (_ id: Any, _ newValue: Any?) -> Void in
let rawObject = id as! CoreStoreManagedObject
customSetter(
O.cs_fromRaw(object: rawObject),
{ (userValue: V) -> Void in
rawObject.setValue(
userValue,
forKvcKey: keyPath,
willSetValue: { $0.cs_toQueryableNativeType() }
)
},
V.cs_fromQueryableNativeType(newValue as! V.QueryableNativeType)!
)
}
}
// MARK: Private
private let customGetter: (_ `self`: O, _ getValue: () -> V) -> V
private let customSetter: (_ `self`: O, _ setValue: (V) -> Void, _ newValue: V) -> Void
private let customGetter: ((_ `self`: O, _ getValue: () -> V) -> V)?
private let customSetter: ((_ `self`: O, _ setValue: (V) -> Void, _ newValue: V) -> Void)?
}
@@ -263,19 +321,19 @@ public enum ValueContainer<O: CoreStoreObject> {
*/
public init(
_ keyPath: RawKeyPath,
`default`: V? = nil,
`default`: @autoclosure @escaping () -> V? = nil,
isIndexed: Bool = false,
isTransient: Bool = false,
versionHashModifier: String? = nil,
renamingIdentifier: String? = nil,
customGetter: @escaping (_ `self`: O, _ getValue: () -> V?) -> V? = { $1() },
customSetter: @escaping (_ `self`: O, _ setValue: (_ finalNewValue: V?) -> Void, _ originalNewValue: V?) -> Void = { $1($2) },
customGetter: ((_ `self`: O, _ getValue: () -> V?) -> V?)? = nil,
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V?) -> Void, _ originalNewValue: V?) -> Void)? = nil,
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
self.keyPath = keyPath
self.isIndexed = isIndexed
self.isTransient = isTransient
self.defaultValue = `default`?.cs_toQueryableNativeType()
self.defaultValue = { `default`()?.cs_toQueryableNativeType() }
self.versionHashModifier = versionHashModifier
self.renamingIdentifier = renamingIdentifier
self.customGetter = customGetter
@@ -290,45 +348,59 @@ public enum ValueContainer<O: CoreStoreObject> {
get {
let object = self.parentObject() as! O
CoreStore.assert(
object.rawObject!.isRunningInAllowedQueue() == true,
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
)
return self.customGetter(
object,
{ () -> V? in
return object.rawObject!.getValue(
forKvcKey: self.keyPath,
didGetValue: { ($0 as! V.QueryableNativeType?).flatMap(V.cs_fromQueryableNativeType) }
)
}
self.parentObject != nil,
"Attempted to access 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 value outside it's designated queue."
)
let customGetter = (self.customGetter ?? { $1() })
return customGetter(
object,
{ () -> V? in
return object.rawObject!.getValue(
forKvcKey: self.keyPath,
didGetValue: { ($0 as! V.QueryableNativeType?).flatMap(V.cs_fromQueryableNativeType) }
)
}
)
}
}
set {
let object = self.parentObject() as! O
CoreStore.assert(
object.rawObject!.isRunningInAllowedQueue() == true,
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
)
CoreStore.assert(
object.rawObject!.isEditableInContext() == true,
"Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction."
)
self.customSetter(
object,
{ (newValue: V?) -> Void in
object.rawObject!.setValue(
newValue,
forKvcKey: self.keyPath,
willSetValue: { $0?.cs_toQueryableNativeType() }
)
},
newValue
self.parentObject != nil,
"Attempted to access 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 value outside it's designated queue."
)
CoreStore.assert(
self.isTransient || 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,
forKvcKey: self.keyPath,
willSetValue: { $0?.cs_toQueryableNativeType() }
)
},
newValue
)
}
}
}
@@ -344,21 +416,65 @@ public enum ValueContainer<O: CoreStoreObject> {
internal let isOptional = true
internal let isIndexed: Bool
internal let isTransient: Bool
internal let defaultValue: Any?
internal let versionHashModifier: String?
internal let renamingIdentifier: String?
internal let defaultValue: () -> Any?
internal let affectedByKeyPaths: () -> Set<String>
internal weak var parentObject: CoreStoreObject?
internal var parentObject: () -> CoreStoreObject = {
internal private(set) lazy var getter: CoreStoreManagedObject.CustomGetter? = cs_lazy { [unowned self] in
CoreStore.abort("Attempted to access values from a \(cs_typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types.")
guard let customGetter = self.customGetter else {
return nil
}
let keyPath = self.keyPath
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.QueryableNativeType?).flatMap(V.cs_fromQueryableNativeType) }
)
}
)
return value?.cs_toQueryableNativeType()
}
}
internal private(set) lazy var setter: CoreStoreManagedObject.CustomSetter? = cs_lazy { [unowned self] in
guard let customSetter = self.customSetter else {
return nil
}
let keyPath = self.keyPath
return { (_ id: Any, _ newValue: Any?) -> Void in
let rawObject = id as! CoreStoreManagedObject
customSetter(
O.cs_fromRaw(object: rawObject),
{ (userValue: V?) -> Void in
rawObject.setValue(
userValue,
forKvcKey: keyPath,
willSetValue: { $0?.cs_toQueryableNativeType() }
)
},
(newValue as! V.QueryableNativeType?).flatMap(V.cs_fromQueryableNativeType)
)
}
}
// MARK: Private
private let customGetter: (_ `self`: O, _ getValue: () -> V?) -> V?
private let customSetter: (_ `self`: O, _ setValue: (V?) -> Void, _ newValue: V?) -> Void
private let customGetter: ((_ `self`: O, _ getValue: () -> V?) -> V?)?
private let customSetter: ((_ `self`: O, _ setValue: (V?) -> Void, _ newValue: V?) -> Void)?
}
}
@@ -391,8 +507,8 @@ public extension ValueContainer.Required where V: EmptyableAttributeType {
isTransient: Bool = false,
versionHashModifier: String? = nil,
renamingIdentifier: String? = nil,
customGetter: @escaping (_ `self`: O, _ getValue: () -> V) -> V = { $1() },
customSetter: @escaping (_ `self`: O, _ setValue: (_ finalNewValue: V) -> Void, _ originalNewValue: V) -> Void = { $1($2) },
customGetter: ((_ `self`: O, _ getValue: () -> V) -> V)? = nil,
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V) -> Void, _ originalNewValue: V) -> Void)? = nil,
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
self.init(
@@ -463,13 +579,13 @@ public enum TransformableContainer<O: CoreStoreObject> {
*/
public init(
_ keyPath: RawKeyPath,
`default`: V,
`default`: @autoclosure @escaping () -> V,
isIndexed: Bool = false,
isTransient: Bool = false,
versionHashModifier: String? = nil,
renamingIdentifier: String? = nil,
customGetter: @escaping (_ `self`: O, _ getValue: () -> V) -> V = { $1() },
customSetter: @escaping (_ `self`: O, _ setValue: (_ finalNewValue: V) -> Void, _ originalNewValue: V) -> Void = { $1($2) },
customGetter: ((_ `self`: O, _ getValue: () -> V) -> V)? = nil,
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V) -> Void, _ originalNewValue: V) -> Void)? = nil,
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
self.keyPath = keyPath
@@ -490,44 +606,58 @@ public enum TransformableContainer<O: CoreStoreObject> {
get {
let object = self.parentObject() as! O
CoreStore.assert(
object.rawObject!.isRunningInAllowedQueue() == true,
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
)
return self.customGetter(
object,
{ () -> V in
return object.rawObject!.getValue(
forKvcKey: self.keyPath,
didGetValue: { $0 as! V }
)
}
self.parentObject != nil,
"Attempted to access 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 value outside it's designated queue."
)
let customGetter = (self.customGetter ?? { $1() })
return customGetter(
object,
{ () -> V in
return object.rawObject!.getValue(
forKvcKey: self.keyPath,
didGetValue: { $0 as! V }
)
}
)
}
}
set {
let object = self.parentObject() as! O
CoreStore.assert(
object.rawObject!.isRunningInAllowedQueue() == true,
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
)
CoreStore.assert(
object.rawObject!.isEditableInContext() == true,
"Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction."
)
self.customSetter(
object,
{ (newValue: V) -> Void in
object.rawObject!.setValue(
newValue,
forKvcKey: self.keyPath
)
},
newValue
self.parentObject != nil,
"Attempted to access 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 value outside it's designated queue."
)
CoreStore.assert(
self.isTransient || 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,
forKvcKey: self.keyPath
)
},
newValue
)
}
}
}
@@ -544,21 +674,55 @@ public enum TransformableContainer<O: CoreStoreObject> {
internal let isOptional = false
internal let isIndexed: Bool
internal let isTransient: Bool
internal let defaultValue: Any?
internal let versionHashModifier: String?
internal let renamingIdentifier: String?
internal let defaultValue: () -> Any?
internal let affectedByKeyPaths: () -> Set<String>
internal weak var parentObject: CoreStoreObject?
internal var parentObject: () -> CoreStoreObject = {
internal private(set) lazy var getter: CoreStoreManagedObject.CustomGetter? = cs_lazy { [unowned self] in
CoreStore.abort("Attempted to access values from a \(cs_typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types.")
guard let customGetter = self.customGetter else {
return nil
}
let keyPath = self.keyPath
return { (_ id: Any) -> Any? in
let rawObject = id as! CoreStoreManagedObject
return customGetter(
O.cs_fromRaw(object: rawObject),
{ rawObject.getValue(forKvcKey: keyPath) as! V }
)
}
}
internal private(set) lazy var setter: CoreStoreManagedObject.CustomSetter? = cs_lazy { [unowned self] in
guard let customSetter = self.customSetter else {
return nil
}
let keyPath = self.keyPath
return { (_ id: Any, _ newValue: Any?) -> Void in
let rawObject = id as! CoreStoreManagedObject
customSetter(
O.cs_fromRaw(object: rawObject),
{ (userValue: V) -> Void in
rawObject.setValue(userValue, forKvcKey: keyPath)
},
newValue as! V
)
}
}
// MARK: Private
private let customGetter: (_ `self`: O, _ getValue: () -> V) -> V
private let customSetter: (_ `self`: O, _ setValue: (V) -> Void, _ newValue: V) -> Void
private let customGetter: ((_ `self`: O, _ getValue: () -> V) -> V)?
private let customSetter: ((_ `self`: O, _ setValue: (V) -> Void, _ newValue: V) -> Void)?
}
@@ -601,13 +765,13 @@ public enum TransformableContainer<O: CoreStoreObject> {
*/
public init(
_ keyPath: RawKeyPath,
`default`: V? = nil,
`default`: @autoclosure @escaping () -> V? = nil,
isIndexed: Bool = false,
isTransient: Bool = false,
versionHashModifier: String? = nil,
renamingIdentifier: String? = nil,
customGetter: @escaping (_ `self`: O, _ getValue: () -> V?) -> V? = { $1() },
customSetter: @escaping (_ `self`: O, _ setValue: (_ finalNewValue: V?) -> Void, _ originalNewValue: V?) -> Void = { $1($2) },
customGetter: ((_ `self`: O, _ getValue: () -> V?) -> V?)? = nil,
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V?) -> Void, _ originalNewValue: V?) -> Void)? = nil,
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
self.keyPath = keyPath
@@ -628,44 +792,58 @@ public enum TransformableContainer<O: CoreStoreObject> {
get {
let object = self.parentObject() as! O
CoreStore.assert(
object.rawObject!.isRunningInAllowedQueue() == true,
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
)
return self.customGetter(
object,
{ () -> V? in
return object.rawObject!.getValue(
forKvcKey: self.keyPath,
didGetValue: { $0 as! V? }
)
}
self.parentObject != nil,
"Attempted to access 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 value outside it's designated queue."
)
let customGetter = (self.customGetter ?? { $1() })
return customGetter(
object,
{ () -> V? in
return object.rawObject!.getValue(
forKvcKey: self.keyPath,
didGetValue: { $0 as! V? }
)
}
)
}
}
set {
let object = self.parentObject() as! O
CoreStore.assert(
object.rawObject!.isRunningInAllowedQueue() == true,
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
)
CoreStore.assert(
object.rawObject!.isEditableInContext() == true,
"Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction."
)
self.customSetter(
object,
{ (newValue: V?) -> Void in
object.rawObject!.setValue(
newValue,
forKvcKey: self.keyPath
)
},
newValue
self.parentObject != nil,
"Attempted to access 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 value outside it's designated queue."
)
CoreStore.assert(
self.isTransient || 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,
forKvcKey: self.keyPath
)
},
newValue
)
}
}
}
@@ -682,21 +860,63 @@ public enum TransformableContainer<O: CoreStoreObject> {
internal let isOptional = true
internal let isIndexed: Bool
internal let isTransient: Bool
internal let defaultValue: Any?
internal let versionHashModifier: String?
internal let renamingIdentifier: String?
internal let defaultValue: () -> Any?
internal let affectedByKeyPaths: () -> Set<String>
internal weak var parentObject: CoreStoreObject?
internal var parentObject: () -> CoreStoreObject = {
internal private(set) lazy var getter: CoreStoreManagedObject.CustomGetter? = cs_lazy { [unowned self] in
CoreStore.abort("Attempted to access values from a \(cs_typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types.")
guard let customGetter = self.customGetter else {
return nil
}
let keyPath = self.keyPath
return { (_ id: Any) -> Any? in
let rawObject = id as! CoreStoreManagedObject
return customGetter(
O.cs_fromRaw(object: rawObject),
{ rawObject.getValue(forKvcKey: keyPath) as! V? }
)
}
}
internal private(set) lazy var setter: CoreStoreManagedObject.CustomSetter? = cs_lazy { [unowned self] in
let keyPath = self.keyPath
guard let customSetter = self.customSetter else {
guard let _ = self.customGetter else {
return nil
}
return { (_ id: Any, _ newValue: Any?) -> Void in
let rawObject = id as! CoreStoreManagedObject
rawObject.setValue(newValue, forKvcKey: keyPath)
}
}
return { (_ id: Any, _ newValue: Any?) -> Void in
let rawObject = id as! CoreStoreManagedObject
customSetter(
O.cs_fromRaw(object: rawObject),
{ (userValue: V?) -> Void in
rawObject.setValue(userValue, forKvcKey: keyPath)
},
newValue as! V?
)
}
}
// MARK: Private
private let customGetter: (_ `self`: O, _ getValue: () -> V?) -> V?
private let customSetter: (_ `self`: O, _ setValue: (V?) -> Void, _ newValue: V?) -> Void
private let customGetter: ((_ `self`: O, _ getValue: () -> V?) -> V?)?
private let customSetter: ((_ `self`: O, _ setValue: (V?) -> Void, _ newValue: V?) -> Void)?
}
}
@@ -999,9 +1219,11 @@ internal protocol AttributeProtocol: class {
var isOptional: Bool { get }
var isIndexed: Bool { get }
var isTransient: Bool { get }
var defaultValue: Any? { get }
var versionHashModifier: String? { get }
var renamingIdentifier: String? { get }
var defaultValue: () -> Any? { get }
var affectedByKeyPaths: () -> Set<String> { get }
var parentObject: () -> CoreStoreObject { get set }
weak var parentObject: CoreStoreObject? { get set }
var getter: CoreStoreManagedObject.CustomGetter? { get }
var setter: CoreStoreManagedObject.CustomSetter? { get }
}