关于ios:executeFetchRequest引发致命错误:NSArray元素与Swift Array元素类型不匹配

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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 ="[email protected]"

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

    }

}

我跑步时:

1
Contact.execute()

然后编译器抛出此错误:

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

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

1
 let firstContact = result[0] as Contact

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

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

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

我做错了什么?

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

更新:
-----------

如果我得到executeFetchRequest结果作为可选数组,并使用[NSManagedObject]而不是[Contact],它将起作用。

1
2
3
4
5
6
7
8
9
10
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在其答案中显示的类别。


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

enter


在我的情况下,我在Core Data Model Editor中将模块更改为"当前产品模块"。它对我来说很好用。

enter

从数据模型检查器中检查实体中的类和模块,并将类名称设置为实体名称,并将模块设置为"当前产品模块"
类名和模块


我认为这样设置目标名称的前缀是个坏主意
因为如果您想将模型移至其他应用程序中,或更改目标名称,则最终需要再次对其进行更改,因此

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

1
2
3
4
5
6
7
import CoreData

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

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


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

1
2
3
4
5
6
7
if let result: [Contact]? = context.executeFetchRequest(fetch, error: nil) as? [Contact] {

    let firstContact = result[0]

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