删除核心数据中的对象,无法匹配Swift数组元素类型

时间:2015-01-24 22:57:53

标签: ios arrays uitableview swift core-data

当我尝试从核心数据中删除对象时,我收到此错误:

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>但是我也遇到了运行时错误,没有找到错误的线索。

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

1 个答案:

答案 0 :(得分:3)

使用

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

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

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

备注:我建议使用NSFetchedResultsController 在表视图中显示Core Data fetch请求的结果。 FRC有效地管理表视图数据源(可选 分组到部分),并且自动更新表格视图 如果结果集发生变化。