executeFetchRequest抛出致命错误:NSArray元素无法匹配Swift数组元素types
我正在用CoreDatatestingswift,并创build了以下代码:
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
的返回types是NSArray
。 现在在Swift上 ,返回types是[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类加载的时候。 发生这种情况有几个不同的原因,所有这些原因都集中在“核心数据无法在数据模型的类行上find您为该实体指定的类”。
其中的可能性:
– 你为Swift类指定了错误的包
– 你忘了指定class级
– 你拼错了名字
在我的情况下,我忘记指定类作为POB在她的答案显示。
我能够在控制台中重现您的错误信息。 你会得到这个消息,因为你没有在核心数据模型编辑器中正确设置你的实体类名(见下图)。
完成后,您将能够使用您的原始代码与Contact
。 您可以在这里了解更多关于核心数据和命名空间。
在我的情况下,我将模块更改为“核心数据模型编辑器”中的“当前产品模块”。它开始为我工作的很好。
我认为你的问题是,executeFetchRequest返回一个可选的数组,而不是一个数组。 你需要解开它。
if let result: [Contact]? = context.executeFetchRequest(fetch, error: nil) as? [Contact] { let firstContact = result[0] println("/(firstContact.name)") println("/(firstContact.email)") }
我认为这样设置你的目标名称的前缀是个坏主意因为如果你想将你的模型移动到其他应用程序中,或者改变targer的名字,你最终会改变它,
所以还有另一种方法。 如果您现在看看xcode如何生成核心数据实体,就像@A_man所说的,您需要在编辑器中设置当前模块并使用@objc(),如下所示:
import CoreData @objc(Contact) class Contact: NSManagedObject { @NSManaged var name: String? @NSManaged var email: String? }
而且字段必须是可选的,因为它们可以是零
从Data Model Inspector中检查实体中的类和模块,并将类名称设置为实体名称和模块为“当前产品模块” 类名称和模块