【问题标题】:Delete object in core data, failed to match the Swift Array Element type删除核心数据中的对象,未能匹配 Swift 数组元素类型
【发布时间】:2015-03-23 18:01:06
【问题描述】:

当我试图从我的核心数据中删除对象时,我收到了这个错误:

fatal error: NSArray element failed to match the Swift Array Element type

我必须知道为什么会发生这种情况。我的表格视图分为几个部分,也许与它有关?我以前从表视图中删除核心数据从来没有遇到过任何问题,所以这对我来说很奇怪。

我的代码如下所示:

var userList = [User]()
var usernames = [String]()

        viewDidLoad(){
        let appDel:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
        let context:NSManagedObjectContext = appDel.managedObjectContext!

        let fetchReq = NSFetchRequest(entityName: "User")
        let en = NSEntityDescription.entityForName("User", inManagedObjectContext: context)
        let sortDescriptor = NSSortDescriptor(key: "username", ascending: true)
        fetchReq.sortDescriptors = [sortDescriptor]
        fetchReq.propertiesToFetch = ["username"]
        fetchReq.resultType = .DictionaryResultType

        userList = context.executeFetchRequest(fetchReq, error: nil) as [User]
}


        func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {

            let editedCell = self.tv.cellForRowAtIndexPath(indexPath)

            let appDel:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
            let context:NSManagedObjectContext = appDel.managedObjectContext!

            if editingStyle == UITableViewCellEditingStyle.Delete {

                if let tv = tableView as Optional{

                    let textLbl = editedCell?.textLabel?.text
                    let ind = find(usernames, textLbl!)! as Int

                    context.deleteObject(userList[ind] as NSManagedObject)

                    userList.removeAtIndex(ind)

                    tv.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Fade)
                }
          } 
    }

在我的代码中,usernames 数组只是一个数组,其中包含从 userList 的核心数据中检索到的所有用户名。

错误出现在我试图从contextuserList 中删除对象的代码中;两行中的错误相同。我尝试将我的userList 转换为Array<AnyObject>,但随后我也遇到了运行时错误,其中错误的线索为零。

非常感谢任何有关如何解决此问题的建议。

【问题讨论】:

  • User 是 NSManagedObject 的子类吗?如果是这样,你不应该在你的删除中需要“作为 NSManagedObject” - 你拥有它的事实让我怀疑你的子类没有注册并且你得到的是普通的 NSManagedObjects,而不是用户对象,这就是你得到数组类型的原因错误。尝试将 userList 设置为 [NSManagedObject] 而不是 [User]
  • @Paulw11 我现在将 userList 声明为 userList:[NSManagedObject] 并将其检索为“as [NSManagedObject]”,我还尝试在删除中删除“as NSManagedObject”。它仍然不起作用,是的,User 是 NSManagedObject 的子类。
  • 你能设置断点并检查数组吗?
  • @Paulw11 我可以,但我真的不确定我要找什么。
  • 数组中的类型是什么?斯威夫特抱怨它不是你说的那样

标签: ios arrays uitableview swift core-data


【解决方案1】:

fetchReq.resultType = .DictionaryResultType

获取请求

userList = context.executeFetchRequest(fetchReq, error: nil) as [User]

返回 NSDictionary 对象的数组,而不是 User 对象的数组,你只是在用强制转换欺骗编译器 as [User].

出于性能原因,此时 Swift 运行时不会验证 如果所有数组元素都是User 对象,那么这个赋值 成功。但是只要您访问一个数组元素,例如使用

userList[ind]

然后你会得到运行时异常,因为元素类型 (NSDictionary) 与数组类型 (User) 不匹配。

您也不能将字典转换回托管对象, 所以这永远行不通:

context.deleteObject(userList[ind] as NSManagedObject)

最好的解决方案可能只是删除

fetchReq.propertiesToFetch = ["username"]
fetchReq.resultType = .DictionaryResultType

以便获取请求返回User 对象的数组,并且 如有必要,调整其余代码。

您可能会再次查看提出的两种不同解决方案 在https://stackoverflow.com/a/28055573/1187415。 第一个返回一个托管对象数组,第二个返回 字典数组。你在这里所做的是混合 通过将结果类型设置为.DictionaryResultType 的解决方案, 但将结果视为托管对象数组。

备注:我建议使用NSFetchedResultsController 在表格视图中显示核心数据获取请求的结果。 FRC 高效管理表视图数据源(可选 分组为部分),并自动更新表格视图 如果结果集发生变化。

【讨论】:

    猜你喜欢
    • 2016-10-27
    • 1970-01-01
    • 2012-06-17
    • 2016-06-21
    • 2016-11-07
    • 1970-01-01
    • 1970-01-01
    • 2014-08-18
    • 1970-01-01
    相关资源
    最近更新 更多