Swift 3 - NSFetchRequest 不同的结果

Posted

技术标签:

【中文标题】Swift 3 - NSFetchRequest 不同的结果【英文标题】:Swift 3 - NSFetchRequest Distinct Results 【发布时间】:2016-10-22 11:30:08 【问题描述】:

任何帮助表示赞赏。

Xcode 自动更新到 8...我的目标是 ios 9.3

已转换所有代码,但现在有一个问题,我在类似问题中尝试了各种建议!我之前工作的获取请求现在中断了。

我的目标是获得一个不同的列表。应用崩溃上线:

let results = try context.fetch(fetchRequest) 

控制台中描述的错误为:

Could not cast value of type 'NSKnownKeysDictionary1' (0x10fd29328) to 'MyApp.BodyType' (0x10eebc820).

这里是函数

func getBodyTypes() 
            let context = ad.managedObjectContext
            let fetchRequest = NSFetchRequest<BodyType>(entityName: "BodyType")
            fetchRequest.propertiesToFetch = ["name"]
            fetchRequest.returnsDistinctResults = true
            fetchRequest.resultType = NSFetchRequestResultType.dictionaryResultType

            do 
                let results = try context.fetch(fetchRequest)

                for r in results 
                    bodyTypes.append(r.value(forKey: "name") as! String)
                
             catch let err as NSError 
                print(err.debugDescription)
            

如果下面的行被隐藏它不会中断,但是我没有得到我想要的!

fetchRequest.resultType = NSFetchRequestResultType.dictionaryResultType 

我知道我可以使用所有结果 (4300) 并循环遍历它们作为创可贴修复,但这感觉不是解决此问题的正确方法,尤其是因为它以前可以工作!

【问题讨论】:

同样的问题。你解决了吗? 这里也一样:/ 有什么消息吗?我还通过遍历不明显的结果并忽略重复项来暂时解决它。 同样的问题...我将暂时做@datayeah 正在做的事情,但除此之外还无法从 SQL 方面找到任何解决方案。 我下面的解决方案是解决这个问题。无需遍历不明显的结果。相反,在设置获取请求时使用通用类型NSFetchRequestResult;然后将结果字典转换为正确的数据类型。 【参考方案1】:

诀窍是使泛型更通用 - 在您的 fetch 请求中使用 &lt;BodyType&gt; 而不是 &lt;NSFetchRequestResult&gt;

let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "BodyType")

这个获取请求的结果是[Any],所以你需要在使用前转换成合适的字典类型。例如:

func getBodyTypes() 
    let context = ad.managedObjectContext
    // 1) use the more general type, NSFetchRequestResult, here:
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "BodyType")
    fetchRequest.propertiesToFetch = ["name"]
    fetchRequest.returnsDistinctResults = true
    fetchRequest.resultType = NSFetchRequestResultType.dictionaryResultType

    do 
        let results = try context.fetch(fetchRequest)

        // 2) cast the results to the expected dictionary type:
        let resultsDict = results as! [[String: String]]

        for r in resultsDict 
            bodyTypes.append(r["name"])
        

     catch let err as NSError 
        print(err.debugDescription)
    

注意:NSFetchRequestResult是一个协议,被四种类型采用: - NSDictionary, - NSManagedObject, - NSManagedObjectID,和 - NSNumber

通常,我们将它与NSManagedObject 一起使用,例如您的BodyType。但是,在这种情况下,由于以下语句,您将获得字典类型:

fetchRequest.resultType = NSFetchRequestResultType.dictionaryResultType

【讨论】:

我面临.resultDistinctResults不被考虑的相同问题,但我使用FetchResultController进行提取,而不是对结果进行所有这些设置。您能否看一下我的代码,看看您是否发现其中有什么问题?这是我的问题:***.com/questions/56168119/… 非常感谢 @vincenzo,我看了你的问题。它实际上并不相同,因为它与投射错误无关,而是与非明确的结果有关。我会进行更深入的研究,看看我是否能找到问题所在。我会在那里回答,如果适用,因为它不适用于这里...... 非常感谢。只是一个提示,因为我正在深入研究这个问题,我正在转向使用普通的 fetch 和 result 作为字典。只要我不使用混合属性类型来获取,它实际上可以按我的意愿工作,只要使用日期它就会返回非不同的结果..也许那里有线索.. 我已经用更新的代码更新了我的问题,因为我发现没有使 fetch 返回不同的结果。我没有通过.propertiesToGroupBy.propertiesToFetch 推进。现在可以了。在将 fetch 用作我的Tableview 的数据源时,我还有一个小问题。如果你还能看到它,那就太好了。再次非常感谢您。 我发现了我的最后一个问题。当我使用FetchResultsController 执行获取时,我也必须将其类型设置为字典。非常感谢您对我的问题感兴趣。【参考方案2】:

我在这个答案中为 Swift 5.x 概述了一个简单的分步方法:https://***.com/a/60101960/171933

【讨论】:

以上是关于Swift 3 - NSFetchRequest 不同的结果的主要内容,如果未能解决你的问题,请参考以下文章

Swift 3 核心数据

Swift - NSFetchRequest 错误

Swift 中 NSFetchRequest 的多个 NSPredicates?

Swift NSFetchRequest 按一个属性分组

NSFetchRequest 上的 Swift2.0 CoreData 问题

Coredata NSFetchRequest DictionaryResultType 空属性 Swift