NSFetchRequest返回的AnyObject数组错误,在XCTestCase中的Swift XCode 6 Beta 4中投射“Swift动态转换失败”

时间:2014-08-02 22:04:17

标签: xcode swift ios8

我知道在here之前已经问过这个问题,但答案并没有解决我的问题,我想发布我的完整测试用例。

我在屏幕截图中设置了我的实体: Entities setup image

我让XCode生成NSManagedObject的子类:

import Foundation
import CoreData

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

它还创建了一个名为LifeList-Bridging-Header.h的头文件,该文件为空。

最后我设置了一个测试用例:

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)
        }
    }
}

以下是运行测试的结果:

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)

2 个答案:

答案 0 :(得分:5)

所有的功劳都归功于jrtuton。有没有办法将答案归于他?

以下是所做的更改:

  1. 从测试目标的编译列表中删除了Goal类。

  2. 为Goal类添加了适当的访问修饰符:

    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. 添加了一个公共init方法:

    public init(entity: NSEntityDescription, insertIntoManagedObjectContext:   NSManagedObjectContext) {
        super.init(entity: entity, insertIntoManagedObjectContext:   insertIntoManagedObjectContext)
    }
    
  4. 在我的测试类中导入LifeList模块:

    import LifeList
    

答案 1 :(得分:0)

试试这个:

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