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 |
我想问题出在
我试图将
1 | Cannot convert the expression's type '[AnyObject]?' to type 'NSArray' |
我做错了什么?
我正在使用:
Xcode 6.0(6A313)GM和
OSX 10.9.4
更新:
-----------
如果我得到
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中正确设置您的实体类名称(请参见下图)。
完成后,您将可以在
在我的情况下,我在Core Data Model Editor中将模块更改为"当前产品模块"。它对我来说很好用。
从数据模型检查器中检查实体中的类和模块,并将类名称设置为实体名称,并将模块设置为"当前产品模块"
类名和模块
我认为这样设置目标名称的前缀是个坏主意
因为如果您想将模型移至其他应用程序中,或更改目标名称,则最终需要再次对其进行更改,因此
所以还有另一种方法。如果您看看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)") } |