Swift:无法将“NSManagedObject”类型的值转换为“data Model.Entity”

Posted

技术标签:

【中文标题】Swift:无法将“NSManagedObject”类型的值转换为“data Model.Entity”【英文标题】:Swift: Could not cast value of type 'NSManagedObject_' to 'dataModel.Entity' 【发布时间】:2015-06-12 14:35:03 【问题描述】:

我真的不知道我需要解释什么,如果需要,请随时向我询问更多代码或解释.. 我正在尝试使用 CoreData 存储从 http POST 请求获得的数据,然后将它们打印在 UITableView 上。

我成功地从 JSON 中获取数据并将它们发送到数据库。问题是当我尝试将数据从数据库发送到 UITableView 时。

这是我第一次使用 Core Data,所以为了了解它是如何工作的,我已经按照我的情况适应了这个教程:https://www.youtube.com/watch?v=UniafUWsvLg

这是我工作的实体:

import Foundation
import CoreData

class Task: NSManagedObject 

    @NSManaged var summary: String
    @NSManaged var status: String
    @NSManaged var responsable: String
    @NSManaged var id: String
    @NSManaged var detail: String
    @NSManaged var date: String
    @NSManaged var context: String


这是准备CoreData工作的代码的一部分,我上面有一些cmets:

//Preparing variables used to get and send datas from DB
let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
var nTask: Task? = nil
var frc : NSFetchedResultsController = NSFetchedResultsController()

func getFetchedResultsController() -> NSFetchedResultsController
    frc = NSFetchedResultsController(fetchRequest: taskFetchRequest(), managedObjectContext: context!, sectionNameKeyPath: nil, cacheName: nil)
    return frc

func taskFetchRequest() -> NSFetchRequest 
    //On which Entity are we working?
    let fetchRequest = NSFetchRequest(entityName: "Task")
    //Which attribute get the Order by. There summary as Ascending
    let sortDescriptor = NSSortDescriptor(key: "summary", ascending: true)
    fetchRequest.sortDescriptors = [sortDescriptor]
    return fetchRequest

现在我已经声明了这一点,我在 viewDidLoad 上将 getFetchedResultsController 的委托设置为 self:

override func viewDidLoad() 
    super.viewDidLoad()

    frc = getFetchedResultsController()
    frc.delegate = self
    frc.performFetch(nil)

这就是我创建指向数据库的链接以从中获取数据的方式:

//Link creation to SQLite DB
        let context = self.context
        let ent = NSEntityDescription.entityForName("Task", inManagedObjectContext: context!)
        let nTask = Task(entity: ent!, insertIntoManagedObjectContext: context)

然后我用从 JSON 中提取的字符串填充我的 nTask,保存上下文并重新加载数据库:

for dict in json2 
    var apps = [String]()


    if let summary = dict["summary"] as? String
        nTask.summary = summary
    


    if let description = dict["description"] as? String
        nTask.detail = description
    


    if let context = dict["context"] as? String
        nTask.context = context
    


    if let due = dict["due"] as? String 
        nTask.date = due
    

    if let status = dict["status"] as? String
        nTask.status = status
    

    if let responsible = dict["responsible"] as? String
        nTask.responsable = responsible
    

    if let id = dict["id"] as? String
        nTask.id = id
    


context?.save(nil)
println(nTask)
self.tableView.reloadData()

当我们使用TableView时,我们必须声明cellForRowAtIndexPathnumberOfRowsInSection,它们是:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 

    var cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("customTableViewCell") as! UITableViewCell
    let task = frc.objectAtIndexPath(indexPath) as! Task
    cell.textLabel?.text = task.summary
    var detail = task.detail
    var context = task.context
    var due = task.date
    var status = task.status
    var responsible = task.responsable

    cell.detailTextLabel?.text = "Contexte: \(context), Detail: \(detail), Status: \(status), Ending date: \(due)"

    return cell


func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

    let numberOfRowsInSection = frc.sections?[section].numberOfObjects
    return numberOfRowsInSection!


错误是我的 cellForRowAtIndexPath 上的let task = frc.objectAtIndexPath(indexPath) as! Task 行。

完整的错误是:Could not cast value of type 'NSManagedObject_Task_' (0x79ebd190) to 'TaskManager.Task' (0xa1f08).

我搜索了半天以上,没有结果。我真的不明白发生在我身上的事情......

很抱歉提供这么多代码,但我不知道出现此错误的位置或原因,所以我必须提供尽可能多的信息.​​.

非常感谢您阅读到最后,感谢您的帮助。

问候。

编辑:

我终于通过做几件事解决了我的问题。我真的不知道哪一个解决了...我在我的Task类上添加了注释@objc(Task),在我的DataModel上我将类更改为Task,检查我的NSManagedObjectModel是let modelURL = NSBundle.mainBundle().URLForResource("TaskManager", withExtension: "momd")!和AppDelegate上的url let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("TaskManager.sqlite") ..

感谢您的帮助。

【问题讨论】:

您在数据模型检查器中对您的任务实体有什么价值。它应该是 NameOfProject.Task 【参考方案1】:

我遇到了类似的问题,就我而言,有效的方法是将这个@objc(NameOfClass) 添加到我的核心数据类定义之上。谢谢!

【讨论】:

【参考方案2】:

试试:

let task = frc.objectAtIndexPath(indexPath) as NSManagedObject

也许你真正遇到的问题不是它的“cellForRowAtIndexPath”中的提取是它的“FOR”:

for dict in json2 
...
if let summary = json2["summary"] as? String
    nTask.summary = summary

...

当你应该从"json2"得到它时,你正在寻找"dict""summary"

【讨论】:

您好,谢谢您的回答。我可以按照你的说法修改它,但是如果我这样做,我将无法编辑单元格的 textLabel (cell.textLabel?.text = task.summary),因为摘要在 NSManagedObject 上不再存在,但在 Task 类上存在,它继承了 NSManagedObject (class Task: NSManagedObject ) 有什么想法吗? 看看我在答案中添加了什么。

以上是关于Swift:无法将“NSManagedObject”类型的值转换为“data Model.Entity”的主要内容,如果未能解决你的问题,请参考以下文章

NSManagedObject 上的 Swift 扩展

CoreData 无法正确“创建 NSManagedObject 子类”Swift

无法通过 Swift 扩展向objective-c NSManagedObject 子类添加方法

Swift CoreData:无法在 NSManagedObject 上调用指定的初始化程序

Swift:返回 self 类型的数组

将 NSManagedObject 数组与另一个“对象”类型 Swift 2 的数组进行比较