AnyObject array returned by NSFetchRequest errors

2019-08-07 18:24发布

问题:

I know this has been asked before here but the answer did not solve my problem, and I wanted to post my full test case.

I setup my Entities as in the screenshot: Entities setup image

I had XCode generate a subclass of NSManagedObject:

import Foundation
import CoreData

class Goal: NSManagedObject {
    @NSManaged var displayDesc: String
    @NSManaged var motivation: String
    @NSManaged var cratedDate: NSDate
    @NSManaged var goalType: NSNumber
}

It also created a header file called LifeList-Bridging-Header.h that is empty.

Finally I setup a test case:

import UIKit
import XCTest
import CoreData

class CastExceptionTest: XCTestCase {
    var _managedObjectContext: NSManagedObjectContext? = nil
    var _persistentStoreCoordinator: NSPersistentStoreCoordinator? = nil
    var _managedObjectModel: NSManagedObjectModel? = nil

    var applicationDocumentsDirectory: NSURL {
        let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
        return urls[urls.count-1] as NSURL
    }

    var managedObjectContext: NSManagedObjectContext {
        if !_managedObjectContext {
            let coordinator = self.persistentStoreCoordinator
            if coordinator != nil {
                _managedObjectContext = NSManagedObjectContext()
                _managedObjectContext!.persistentStoreCoordinator = coordinator
            }
        }
        return _managedObjectContext!
    }

    var managedObjectModel: NSManagedObjectModel {
        if !_managedObjectModel {
            //The data model is just an Entity named Goal with 4 attributes one named displayDesc.
            let modelURL = NSBundle.mainBundle().URLForResource("LifeList", withExtension: "momd")
            _managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)
        }
        return _managedObjectModel!
    }

    var persistentStoreCoordinator: NSPersistentStoreCoordinator {
        if !_persistentStoreCoordinator {
            let storeURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent("CastExceptionTest.sqlite")
            var error: NSError? = nil
            _persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
            if _persistentStoreCoordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil, error: &error) == nil {
                abort()
            }
        }
        return _persistentStoreCoordinator!
    }

    func testCase() {
        //Create and save a new Goal
        let entityDescription = NSEntityDescription.entityForName("Goal", inManagedObjectContext: managedObjectContext)
        let goal = Goal(entity: entityDescription, insertIntoManagedObjectContext: managedObjectContext)
        goal.displayDesc = "Test text"
        var error:NSError?
        managedObjectContext.save(&error)

        //Load the entities
        let fetch = NSFetchRequest(entityName: "Goal")
        let objectArray: [AnyObject]? = managedObjectContext.executeFetchRequest(fetch, error: &error)
        for object in objectArray! {
            let goal = object as Goal
            print(goal.displayDesc)
        }
    }
}

The following is the outcome of running the test:

libswift_stdlib_core.dylib`swift_dynamicCastClassUnconditional:
0x105b147c0:  pushq  %rbp
0x105b147c1:  movq   %rsp, %rbp
0x105b147c4:  pushq  %r14
0x105b147c6:  pushq  %rbx
0x105b147c7:  movq   %rsi, %rbx
0x105b147ca:  movq   %rdi, %r14
0x105b147cd:  testq  %r14, %r14
0x105b147d0:  je     0x105b147fe               ; swift_dynamicCastClassUnconditional + 62
0x105b147d2:  movabsq $-0x7fffffffffffffff, %rax
0x105b147dc:  andq   %r14, %rax
0x105b147df:  jne    0x105b147fe               ; swift_dynamicCastClassUnconditional + 62
0x105b147e1:  movq   %r14, %rdi
0x105b147e4:  callq  0x105b29764               ; symbol stub for: object_getClass
0x105b147e9:  nopl   (%rax)
0x105b147f0:  cmpq   %rbx, %rax
0x105b147f3:  je     0x105b1480d               ; swift_dynamicCastClassUnconditional + 77
0x105b147f5:  movq   0x8(%rax), %rax
0x105b147f9:  testq  %rax, %rax
0x105b147fc:  jne    0x105b147f0               ; swift_dynamicCastClassUnconditional + 48
0x105b147fe:  leaq   0x1da7d(%rip), %rax       ; "Swift dynamic cast failed"
0x105b14805:  movq   %rax, 0x88da4(%rip)       ; gCRAnnotations + 8
0x105b1480c:  int3   
0x105b1480d:  movq   %r14, %rax
0x105b14810:  popq   %rbx
0x105b14811:  popq   %r14
0x105b14813:  popq   %rbp
0x105b14814:  retq   
0x105b14815:  nopw   %cs:(%rax,%rax)

 

回答1:

All credit goes to jrtuton for this. Is there some way to attribute the answer to him?

Here are the changes made:

  1. Removed the Goal class from the compile list for the test target.

  2. Added proper access modifiers to the Goal class:

    public class Goal: NSManagedObject {
    
        @NSManaged public var displayDesc: String
        @NSManaged public var motivation: String
        @NSManaged public var cratedDate: NSDate
        @NSManaged public var goalType: NSNumber
    
  3. Added a public init method:

    public init(entity: NSEntityDescription, insertIntoManagedObjectContext:   NSManagedObjectContext) {
        super.init(entity: entity, insertIntoManagedObjectContext:   insertIntoManagedObjectContext)
    }
    
  4. Imported the LifeList module in my test class:

    import LifeList
    


回答2:

Try this:

@objc(CastExceptionTest)    // add this line
class CastExceptionTest: XCTestCase {
    ...
}


标签: xcode swift ios8