executeFetchRequest抛出致命错误:NSArray元素无法匹配Swift数组元素类型

时间:2014-09-17 17:48:35

标签: ios arrays core-data collections swift

我正在使用CoreData测试swift,我创建了以下代码:

import UIKit
import CoreData

class Contact: NSManagedObject {

    @NSManaged var name: String
    @NSManaged var email: String

    class func execute(){
        let appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
        let context:NSManagedObjectContext = appDel.managedObjectContext!

        let entityDescripition = NSEntityDescription.entityForName("Contact", inManagedObjectContext: context)
        let contact = Contact(entity: entityDescripition!, insertIntoManagedObjectContext: context)

        contact.name = "john Apleesee"
        contact.email = "john@apple.com"

        context.save(nil)

        let fetch:NSFetchRequest = NSFetchRequest(entityName: "Contact")
        var result = context.executeFetchRequest(fetch, error: nil) as [Contact]

        let firstContact = result[0] as Contact  //  <<-- error !

        println("\(firstContact.name)")
        println("\(firstContact.email)")

    }

}

当我跑步时:

Contact.execute()

然后编译器抛出此错误:

fatal error: NSArray element failed to match the Swift Array Element type

当我尝试从数组中获取值时:

 let firstContact = result[0] as Contact

我想问题出在executeFetchRequest。在 Objective-c 上,executeFetchRequest的返回类型为NSArray。现在,在 Swift 上,返回类型为[AnyObject]?

我尝试将[AnyObject]?结果转换为NSArray,但Xcode表示:

 Cannot convert the expression's type '[AnyObject]?' to type 'NSArray' 

我做错了什么?

我正在使用: Xcode 6.0(6A313)GM和 OSX 10.9.4

更新
-----------

如果我将executeFetchRequest结果作为可选数组并使用[NSManagedObject]代替[Contact],则可以正常运行。

if let result: [NSManagedObject]? = context.executeFetchRequest(fetch, error: nil) as? [NSManagedObject] {

        let firstContact: NSManagedObject = result![0]

        let name = firstContact.valueForKey("name") as String
        let email = firstContact.valueForKey("email") as String

        println("\(name)")
        println("\(email)")
    }

UPDATE2:
-----------

当使用NSManagedObject类未加载实体实例时会发生此类问题。发生这种情况的原因有几个,所有这些都集中在“核心数据无法在数据模型的类行中找到您为该实体指定的类。”

其中的可能性:
- 您为Swift类指定了错误的包 - 你忘了指定班级 - 你拼错了名字

在我的情况下,我忘记在她的答案中将课程指定为POB。

5 个答案:

答案 0 :(得分:33)

我能够在控制台中重现您的错误消息。您收到此消息是因为您未在Core Data Model Editor中正确设置实体类名称(参见下图)。

enter image description here

完成后,您将能够将原始代码与Contact子类一起使用。您可以了解有关核心数据和命名空间here的更多信息。

答案 1 :(得分:6)

在我的情况下,我在Core Data Model Editor中将模块更改为“当前产品模块”。它开始正常工作。

enter image description here

答案 2 :(得分:0)

我认为设置目标名称的前缀是个坏主意,例如this 因为如果您想将模型移动到其他应用程序中,或者更改目标名称,您最终会再次更改它,

所以还有另一种方式。如果你看看xcode现在如何生成核心数据实体,@ A_man说你需要在编辑器中设置当前模块并使用@objc(),如下所示:

import CoreData

@objc(Contact)
class Contact: NSManagedObject {
    @NSManaged var name: String?
    @NSManaged var email: String?
}

字段必须是可选的,因为它们可以是nil

答案 3 :(得分:0)

从数据模型检查器中检查实体中的类和模块,并将类名称设置为实体名称,将模块设置为“当前产品模块” Class name and Module

答案 4 :(得分:-1)

我认为你的问题是executeFetchRequest返回一个可选数组,而不是数组。你需要打开它。

if let result: [Contact]? = context.executeFetchRequest(fetch, error: nil) as? [Contact] {

    let firstContact = result[0]

    println("/(firstContact.name)")
    println("/(firstContact.email)")
}