Originally created by @sidmani on GitHub (Aug 16, 2017).
There's a limitation in fetchExisting at the moment- all subclass type information is lost when applying fetchExisting on a variable with a superclass type. Check out this code:
class Foo: CoreStoreObject { }
class Bar: Foo { }
let someBar: Foo = CoreStore.fetchOne(From<Bar>(), ....)
// ....
let newBar = CoreStore.fetchExisting(someBar)
newBar is Foo // true
newBar is Bar // false
newBar now not only has type Foo, but is actually a Foo, and not just a Bar stored in a variable with type Foo. IMO, this is rather dangerous because it's required to call fetchExisting when entering and exiting transactions, and using variables with a superclass type is a common pattern if there are multiple subclasses. This issue silently stops subclass overrides of methods from being called- I didn't even notice until my unit tests caught it.
I'm going to play around with the code and see what I can come up with. Would appreciate your input @JohnEstropia (and I'm willing to author a pull request if you agree that this needs fixing).
edit: deleted irrelevant attempt at solving problem
Originally created by @sidmani on GitHub (Aug 16, 2017).
There's a limitation in fetchExisting at the moment- all subclass type information is lost when applying fetchExisting on a variable with a superclass type. Check out this code:
```
class Foo: CoreStoreObject { }
class Bar: Foo { }
let someBar: Foo = CoreStore.fetchOne(From<Bar>(), ....)
// ....
let newBar = CoreStore.fetchExisting(someBar)
newBar is Foo // true
newBar is Bar // false
```
newBar now not only has type Foo, but is actually a Foo, and not just a Bar stored in a variable with type Foo. IMO, this is rather dangerous because it's required to call fetchExisting when entering and exiting transactions, and using variables with a superclass type is a common pattern if there are multiple subclasses. This issue silently stops subclass overrides of methods from being called- I didn't even notice until my unit tests caught it.
I'm going to play around with the code and see what I can come up with. Would appreciate your input @JohnEstropia (and I'm willing to author a pull request if you agree that this needs fixing).
edit: deleted irrelevant attempt at solving problem
adam
added the fixed label 2025-12-29 15:25:59 +01:00
Looking through the code, it seems that this behavior could even be inconsistent between invocations of the method- code from fetchExisting (NSManagedObjectContext+Querying.swift)
let existingRawObject = try self.existingObject(with: rawObject.objectID)
if existingRawObject === rawObject {
return object // will preserve subclass
}
return T.cs_fromRaw(object: existingRawObject) // will not preserve subclass
Unless I'm missing something basic, it seems like modifying this method is the way to go.
@sidmani commented on GitHub (Aug 16, 2017):
Looking through the code, it seems that this behavior could even be inconsistent between invocations of the method- code from fetchExisting (NSManagedObjectContext+Querying.swift)
```
let existingRawObject = try self.existingObject(with: rawObject.objectID)
if existingRawObject === rawObject {
return object // will preserve subclass
}
return T.cs_fromRaw(object: existingRawObject) // will not preserve subclass
```
Unless I'm missing something basic, it seems like modifying this method is the way to go.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Originally created by @sidmani on GitHub (Aug 16, 2017).
There's a limitation in fetchExisting at the moment- all subclass type information is lost when applying fetchExisting on a variable with a superclass type. Check out this code:
newBar now not only has type Foo, but is actually a Foo, and not just a Bar stored in a variable with type Foo. IMO, this is rather dangerous because it's required to call fetchExisting when entering and exiting transactions, and using variables with a superclass type is a common pattern if there are multiple subclasses. This issue silently stops subclass overrides of methods from being called- I didn't even notice until my unit tests caught it.
I'm going to play around with the code and see what I can come up with. Would appreciate your input @JohnEstropia (and I'm willing to author a pull request if you agree that this needs fixing).
edit: deleted irrelevant attempt at solving problem
@sidmani commented on GitHub (Aug 16, 2017):
Looking through the code, it seems that this behavior could even be inconsistent between invocations of the method- code from fetchExisting (NSManagedObjectContext+Querying.swift)
Unless I'm missing something basic, it seems like modifying this method is the way to go.
@JohnEstropia commented on GitHub (Aug 16, 2017):
Ah, good catch. Thanks!
@JohnEstropia commented on GitHub (Aug 16, 2017):
Merged the PR to the Swift 4 branch. Will cherry-pick into develop and Swift3.2 branches as well.