We have an application with a fairly broad Core Data model with many custom subclasses implemented in Objective-C, but which are also used by the growing part of the application written in Swift. (What it costs: we are building with Xcode 7.3.1 against iOS 9.3, and Swift code is thus 2.2.)
There is a helper function written in Swift that looks like this:
extension NSManagedObject { func inContext<T: NSManagedObject>(moc: NSManagedObjectContext) -> T? { guard self.managedObjectContext != moc else { return (self as! T) } do { let obj = try moc.existingObjectWithID(self.objectID) return (obj as! T)
This is called in many places where objects leap contexts. The call code usually looks like this:
let result: ECFoo? = foo.inContext(managedObjectContext)
This works flawlessly in application debug builds. But with optimization turned on, I come across a case where this call fails in the line marked by me, where the selected object is dropped from NSManagedObject into the correct subclass. The stack trace begins with swift_dynamicCastObjCClassUnconditional , and the message that is written to the console:
Cannot pass value of type "ECFoo_Foo_" (0x7fb857d2c250) to "ECFoo_Foo_" (0x7fb857d2c250).
If I put a breakpoint on this line, then what I'm trying to do looks great in the debugger console:
(lldb) po moc.existingObjectWithID (self.objectID) is ECFoo
truth
This is very confusing, because here the type is clearly the same on both sides, and both of them seem to be a dynamically generated subclass, rather than the formal class that it should aim for (based on the output of the call code). I can only assume that some of the information is optimized, which is necessary for this work, but I'm not quite sure how to fix it.
optimization casting ios swift core-data
Sixten Otto Aug 23 '16 at 19:36 2016-08-23 19:36
source share