From ab40532801840fc789ac9b8de57e1b2e367e0e74 Mon Sep 17 00:00:00 2001 From: John Estropia Date: Tue, 18 Sep 2018 23:50:14 +0900 Subject: [PATCH] fix issue with early-deallocated CoreStoreObjects --- CoreStore.podspec | 4 +- Sources/AttributeProtocol.swift | 2 +- Sources/CoreStoreObject.swift | 6 +-- Sources/Info.plist | 2 +- Sources/Relationship.swift | 60 +++++++++++++++--------------- Sources/RelationshipProtocol.swift | 2 +- Sources/Transformable.swift | 48 ++++++++++++------------ Sources/Value.swift | 48 ++++++++++++------------ 8 files changed, 86 insertions(+), 86 deletions(-) diff --git a/CoreStore.podspec b/CoreStore.podspec index 20e0c36..cf1da01 100644 --- a/CoreStore.podspec +++ b/CoreStore.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "CoreStore" - s.version = "5.3.0" - s.swift_version = "4.1" + s.version = "5.3.1" + s.swift_version = "4.2" s.license = "MIT" s.summary = "Unleashing the real power of Core Data with the elegance and safety of Swift" s.homepage = "https://github.com/JohnEstropia/CoreStore" diff --git a/Sources/AttributeProtocol.swift b/Sources/AttributeProtocol.swift index 11c3849..3649bb8 100644 --- a/Sources/AttributeProtocol.swift +++ b/Sources/AttributeProtocol.swift @@ -41,7 +41,7 @@ internal protocol AttributeProtocol: class { var renamingIdentifier: () -> String? { get } var defaultValue: () -> Any? { get } var affectedByKeyPaths: () -> Set { get } - var parentObject: CoreStoreObject? { get set } + var rawObject: CoreStoreManagedObject? { get set } var getter: CoreStoreManagedObject.CustomGetter? { get } var setter: CoreStoreManagedObject.CustomSetter? { get } } diff --git a/Sources/CoreStoreObject.swift b/Sources/CoreStoreObject.swift index 46622fc..339cf46 100644 --- a/Sources/CoreStoreObject.swift +++ b/Sources/CoreStoreObject.swift @@ -93,7 +93,7 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable { } if lhs.isMeta { - return type(of: lhs) == type(of: rhs) + return cs_dynamicType(of: lhs) == cs_dynamicType(of: rhs) } return lhs.rawObject!.isEqual(rhs.rawObject!) } @@ -124,10 +124,10 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable { switch child.value { case let property as AttributeProtocol: - property.parentObject = parentObject + property.rawObject = parentObject.rawObject case let property as RelationshipProtocol: - property.parentObject = parentObject + property.rawObject = parentObject.rawObject default: continue diff --git a/Sources/Info.plist b/Sources/Info.plist index bc8da3a..f17667c 100644 --- a/Sources/Info.plist +++ b/Sources/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 5.3.0 + 5.3.1 CFBundleSignature ???? CFBundleVersion diff --git a/Sources/Relationship.swift b/Sources/Relationship.swift index 2fcc84c..b5591fb 100644 --- a/Sources/Relationship.swift +++ b/Sources/Relationship.swift @@ -244,23 +244,23 @@ public enum RelationshipContainer { internal let versionHashModifier: () -> String? internal let renamingIdentifier: () -> String? internal let affectedByKeyPaths: () -> Set - internal weak var parentObject: CoreStoreObject? + internal var rawObject: CoreStoreManagedObject? internal var nativeValue: NSManagedObject? { get { CoreStore.assert( - self.parentObject != nil, + self.rawObject != 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 + return withExtendedLifetime(self.rawObject!) { (object) in CoreStore.assert( - object.rawObject!.isRunningInAllowedQueue() == true, + object.isRunningInAllowedQueue() == true, "Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue." ) - return object.rawObject!.getValue( + return object.getValue( forKvcKey: self.keyPath, didGetValue: { $0 as! NSManagedObject? } ) @@ -269,20 +269,20 @@ public enum RelationshipContainer { set { CoreStore.assert( - self.parentObject != nil, + self.rawObject != 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 + return withExtendedLifetime(self.rawObject!) { (object) in CoreStore.assert( - object.rawObject!.isRunningInAllowedQueue() == true, + object.isRunningInAllowedQueue() == true, "Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue." ) CoreStore.assert( - object.rawObject!.isEditableInContext() == true, + object.isEditableInContext() == true, "Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction." ) - object.rawObject!.setValue( + object.setValue( newValue, forKvcKey: self.keyPath ) @@ -512,23 +512,23 @@ public enum RelationshipContainer { internal let versionHashModifier: () -> String? internal let renamingIdentifier: () -> String? internal let affectedByKeyPaths: () -> Set - internal weak var parentObject: CoreStoreObject? + internal var rawObject: CoreStoreManagedObject? internal var nativeValue: NSOrderedSet { get { CoreStore.assert( - self.parentObject != nil, + self.rawObject != 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 + return withExtendedLifetime(self.rawObject!) { (object) in CoreStore.assert( - object.rawObject!.isRunningInAllowedQueue() == true, + object.isRunningInAllowedQueue() == true, "Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue." ) - return object.rawObject!.getValue( + return object.getValue( forKvcKey: self.keyPath, didGetValue: { ($0 as! NSOrderedSet?) ?? [] } ) @@ -537,20 +537,20 @@ public enum RelationshipContainer { set { CoreStore.assert( - self.parentObject != nil, + self.rawObject != 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 + return withExtendedLifetime(self.rawObject!) { (object) in CoreStore.assert( - object.rawObject!.isRunningInAllowedQueue() == true, + object.isRunningInAllowedQueue() == true, "Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue." ) CoreStore.assert( - object.rawObject!.isEditableInContext() == true, + object.isEditableInContext() == true, "Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction." ) - object.rawObject!.setValue( + object.setValue( newValue, forKvcKey: self.keyPath ) @@ -785,23 +785,23 @@ public enum RelationshipContainer { internal let versionHashModifier: () -> String? internal let renamingIdentifier: () -> String? internal let affectedByKeyPaths: () -> Set - internal weak var parentObject: CoreStoreObject? + internal var rawObject: CoreStoreManagedObject? internal var nativeValue: NSSet { get { CoreStore.assert( - self.parentObject != nil, + self.rawObject != 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 + return withExtendedLifetime(self.rawObject!) { (object) in CoreStore.assert( - object.rawObject!.isRunningInAllowedQueue() == true, + object.isRunningInAllowedQueue() == true, "Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue." ) - return object.rawObject!.getValue( + return object.getValue( forKvcKey: self.keyPath, didGetValue: { ($0 as! NSSet?) ?? [] } ) @@ -810,20 +810,20 @@ public enum RelationshipContainer { set { CoreStore.assert( - self.parentObject != nil, + self.rawObject != 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 + return withExtendedLifetime(self.rawObject!) { (object) in CoreStore.assert( - object.rawObject!.isRunningInAllowedQueue() == true, + object.isRunningInAllowedQueue() == true, "Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue." ) CoreStore.assert( - object.rawObject!.isEditableInContext() == true, + object.isEditableInContext() == true, "Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction." ) - object.rawObject!.setValue( + object.setValue( newValue, forKvcKey: self.keyPath ) diff --git a/Sources/RelationshipProtocol.swift b/Sources/RelationshipProtocol.swift index 41ba813..c46c669 100644 --- a/Sources/RelationshipProtocol.swift +++ b/Sources/RelationshipProtocol.swift @@ -37,7 +37,7 @@ internal protocol RelationshipProtocol: class { var deleteRule: NSDeleteRule { get } var inverse: (type: CoreStoreObject.Type, keyPath: () -> KeyPathString?) { get } var affectedByKeyPaths: () -> Set { get } - var parentObject: CoreStoreObject? { get set } + var rawObject: CoreStoreManagedObject? { get set } var versionHashModifier: () -> String? { get } var renamingIdentifier: () -> String? { get } var minCount: Int { get } diff --git a/Sources/Transformable.swift b/Sources/Transformable.swift index 09607f6..6eea86c 100644 --- a/Sources/Transformable.swift +++ b/Sources/Transformable.swift @@ -145,43 +145,43 @@ public enum TransformableContainer { get { CoreStore.assert( - self.parentObject != nil, + self.rawObject != 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 + return withExtendedLifetime(self.rawObject!) { (object) in CoreStore.assert( - object.rawObject!.isRunningInAllowedQueue() == true, + object.isRunningInAllowedQueue() == true, "Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue." ) if let customGetter = self.customGetter { - return customGetter(PartialObject(object.rawObject!)) + return customGetter(PartialObject(object)) } - return object.rawObject!.value(forKey: self.keyPath)! as! V + return object.value(forKey: self.keyPath)! as! V } } set { CoreStore.assert( - self.parentObject != nil, + self.rawObject != 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 + return withExtendedLifetime(self.rawObject!) { (object) in CoreStore.assert( - object.rawObject!.isRunningInAllowedQueue() == true, + object.isRunningInAllowedQueue() == true, "Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue." ) CoreStore.assert( - object.rawObject!.isEditableInContext() == true, + object.isEditableInContext() == true, "Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction." ) if let customSetter = self.customSetter { - return customSetter(PartialObject(object.rawObject!), newValue) + return customSetter(PartialObject(object), newValue) } - object.rawObject!.setValue( + object.setValue( newValue, forKey: self.keyPath ) @@ -205,7 +205,7 @@ public enum TransformableContainer { internal let renamingIdentifier: () -> String? internal let defaultValue: () -> Any? internal let affectedByKeyPaths: () -> Set - internal weak var parentObject: CoreStoreObject? + internal var rawObject: CoreStoreManagedObject? internal private(set) lazy var getter: CoreStoreManagedObject.CustomGetter? = cs_lazy { [unowned self] in @@ -358,43 +358,43 @@ public enum TransformableContainer { get { CoreStore.assert( - self.parentObject != nil, + self.rawObject != 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 + return withExtendedLifetime(self.rawObject!) { (object) in CoreStore.assert( - object.rawObject!.isRunningInAllowedQueue() == true, + object.isRunningInAllowedQueue() == true, "Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue." ) if let customGetter = self.customGetter { - return customGetter(PartialObject(object.rawObject!)) + return customGetter(PartialObject(object)) } - return object.rawObject!.value(forKey: self.keyPath) as! V? + return object.value(forKey: self.keyPath) as! V? } } set { CoreStore.assert( - self.parentObject != nil, + self.rawObject != 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 + return withExtendedLifetime(self.rawObject!) { (object) in CoreStore.assert( - object.rawObject!.isRunningInAllowedQueue() == true, + object.isRunningInAllowedQueue() == true, "Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue." ) CoreStore.assert( - object.rawObject!.isEditableInContext() == true, + object.isEditableInContext() == true, "Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction." ) if let customSetter = self.customSetter { - return customSetter(PartialObject(object.rawObject!), newValue) + return customSetter(PartialObject(object), newValue) } - object.rawObject!.setValue( + object.setValue( newValue, forKey: self.keyPath ) @@ -418,7 +418,7 @@ public enum TransformableContainer { internal let renamingIdentifier: () -> String? internal let defaultValue: () -> Any? internal let affectedByKeyPaths: () -> Set - internal weak var parentObject: CoreStoreObject? + internal var rawObject: CoreStoreManagedObject? internal private(set) lazy var getter: CoreStoreManagedObject.CustomGetter? = cs_lazy { [unowned self] in diff --git a/Sources/Value.swift b/Sources/Value.swift index c704f8c..55a6469 100644 --- a/Sources/Value.swift +++ b/Sources/Value.swift @@ -138,45 +138,45 @@ public enum ValueContainer { get { CoreStore.assert( - self.parentObject != nil, + self.rawObject != 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 + return withExtendedLifetime(self.rawObject!) { (object) in CoreStore.assert( - object.rawObject!.isRunningInAllowedQueue() == true, + object.isRunningInAllowedQueue() == true, "Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue." ) if let customGetter = self.customGetter { - return customGetter(PartialObject(object.rawObject!)) + return customGetter(PartialObject(object)) } return V.cs_fromQueryableNativeType( - object.rawObject!.value(forKey: self.keyPath)! as! V.QueryableNativeType + object.value(forKey: self.keyPath)! as! V.QueryableNativeType )! } } set { CoreStore.assert( - self.parentObject != nil, + self.rawObject != 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 + return withExtendedLifetime(self.rawObject!) { (object) in CoreStore.assert( - object.rawObject!.isRunningInAllowedQueue() == true, + object.isRunningInAllowedQueue() == true, "Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue." ) CoreStore.assert( - object.rawObject!.isEditableInContext() == true, + object.isEditableInContext() == true, "Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction." ) if let customSetter = self.customSetter { - return customSetter(PartialObject(object.rawObject!), newValue) + return customSetter(PartialObject(object), newValue) } - return object.rawObject!.setValue( + return object.setValue( newValue.cs_toQueryableNativeType(), forKey: self.keyPath ) @@ -200,7 +200,7 @@ public enum ValueContainer { internal let renamingIdentifier: () -> String? internal let defaultValue: () -> Any? internal let affectedByKeyPaths: () -> Set - internal weak var parentObject: CoreStoreObject? + internal var rawObject: CoreStoreManagedObject? internal private(set) lazy var getter: CoreStoreManagedObject.CustomGetter? = cs_lazy { [unowned self] in @@ -351,44 +351,44 @@ public enum ValueContainer { get { CoreStore.assert( - self.parentObject != nil, + self.rawObject != 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 + return withExtendedLifetime(self.rawObject!) { (object) in CoreStore.assert( - object.rawObject!.isRunningInAllowedQueue() == true, + object.isRunningInAllowedQueue() == true, "Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue." ) if let customGetter = self.customGetter { - return customGetter(PartialObject(object.rawObject!)) + return customGetter(PartialObject(object)) } - return (object.rawObject!.value(forKey: self.keyPath) as! V.QueryableNativeType?) + return (object.value(forKey: self.keyPath) as! V.QueryableNativeType?) .flatMap(V.cs_fromQueryableNativeType) } } set { CoreStore.assert( - self.parentObject != nil, + self.rawObject != 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 + return withExtendedLifetime(self.rawObject!) { (object) in CoreStore.assert( - object.rawObject!.isRunningInAllowedQueue() == true, + object.isRunningInAllowedQueue() == true, "Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue." ) CoreStore.assert( - object.rawObject!.isEditableInContext() == true, + object.isEditableInContext() == true, "Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction." ) if let customSetter = self.customSetter { - return customSetter(PartialObject(object.rawObject!), newValue) + return customSetter(PartialObject(object), newValue) } - object.rawObject!.setValue( + object.setValue( newValue?.cs_toQueryableNativeType(), forKey: self.keyPath ) @@ -412,7 +412,7 @@ public enum ValueContainer { internal let renamingIdentifier: () -> String? internal let defaultValue: () -> Any? internal let affectedByKeyPaths: () -> Set - internal weak var parentObject: CoreStoreObject? + internal var rawObject: CoreStoreManagedObject? internal private(set) lazy var getter: CoreStoreManagedObject.CustomGetter? = cs_lazy { [unowned self] in