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

Delete object in core data, failed to match the Swift Array Element type

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

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

而且我必须弄清楚为什么会这样。我的 table 视图被分成几个部分,也许这与它有关?我以前从未遇到过从 table 视图中删除核心数据的问题,所以这对我来说很奇怪。

我的代码如下所示:

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> 但后来我也遇到了一个运行时错误,零线索表明出了什么问题。

任何有关如何解决此问题的建议都将不胜感激。

fetchReq.resultType = .DictionaryResultType

获取请求

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

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

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

userList[ind]

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

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

context.deleteObject(userList[ind] as NSManagedObject)

最好的解决办法可能就是删除

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

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

您可能会再次查看所提出的两种不同的解决方案 在 。 第一个returns一个托管对象数组,第二个 字典数组。你在这里所做的是 mix 通过将结果类型设置为 .DictionaryResultType 的解决方案, 但将结果视为托管对象数组。

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