【问题标题】:executeFetchRequest throw fatal error: NSArray element failed to match the Swift Array Element typeexecuteFetchRequest 抛出致命错误:NSArray 元素无法匹配 Swift Array 元素类型
【发布时间】:2014-11-11 21:02:10
【问题描述】:

我正在使用 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) 通用和 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)")
    }

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

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

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

在我的情况下,我忘记指定 POB 在她的答案中显示的类。

【问题讨论】:

  • 你为什么在你的NSManagedObject子类中设置-execute:方法来执行NSFetchRequest
  • 我这样做是为了简单。在这里展示问题的简单方法。
  • 你试过用let contact = NSEntityDescription.insertNewObjectForEntityForName("Contact", inManagedObjectContext: context) as Contact代替let contact = Contact(entity: entityDescripition!, insertIntoManagedObjectContext: context)吗?
  • 我猜问题出在executeFetchRequest。在 Objective-c 上,executeFetchRequest 的返回类型是一个 NSArray。现在在 Swift 上,返回类型是 [AnyObject?]。
  • println("/... 替换为 println("\...

标签: ios arrays core-data collections swift


【解决方案1】:

我能够在控制台中重现您的错误消息。您收到此消息是因为您没有在核心数据模型编辑器中正确设置实体类名称(见下图)。

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

【讨论】:

  • 像魅力一样工作!非常感谢!:)
  • 在那个类字段中,我不能加“.”
【解决方案2】:

就我而言,我在核心数据模型编辑器中将模块更改为“当前产品模块”。它开始对我来说很好。

【讨论】:

    【解决方案3】:

    从 Data Model Inspector 中检查 Entity 中的类和模块,并将类名设置为实体名称,将模块设置为“当前产品模块” Class name and Module

    【讨论】:

      【解决方案4】:

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

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

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

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

      【讨论】:

        【解决方案5】:

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

        if let result: [Contact]? = context.executeFetchRequest(fetch, error: nil) as? [Contact] {
        
            let firstContact = result[0]
        
            println("/(firstContact.name)")
            println("/(firstContact.email)")
        }
        

        【讨论】:

        • 感谢萨里的回答!它不适用于 Contact,但如果我使用 NSManageObject 而不是 Contact 它运行。不要问我为什么! :)
        猜你喜欢
        • 2014-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多