我正在使用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。
答案 0 :(得分:33)
我能够在控制台中重现您的错误消息。您收到此消息是因为您未在Core Data Model Editor中正确设置实体类名称(参见下图)。
完成后,您将能够将原始代码与Contact
子类一起使用。您可以了解有关核心数据和命名空间here的更多信息。
答案 1 :(得分:6)
答案 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)")
}