我有一个Core Data对象(Order),它有一个返回另一个Core Data对象(OrderWaypoint)数组的方法。
func getOrderedWaypoints() -> [OrderWaypoint] {
let nameDescriptor = NSSortDescriptor(key: "stop_number", ascending: true)
let sorted: [OrderWaypoint] = self.waypoints.sortedArrayUsingDescriptors([nameDescriptor]) as [OrderWaypoint]
return sorted
}
使用以下循环时,主要目标中的所有内容都按预期工作
for waypoint in order.getOrderedWaypoints() {
// do something
}
但是当我在我的测试目标中尝试完全相同的事情时
致命错误:NSArray元素无法与Swift数组元素匹配 型
我已经尝试过投射价值但似乎无法让它发挥作用。任何想法为什么它在主要目标而不是测试目标?
修改
进一步分解它,当我尝试从阵列中取出一个项目时,问题就出现了。
var orderedList: [OrderWaypoint] = order.getOrderedWaypoints()
for var i = 0; i < orderedList.count; i++ {
var waypoint = orderedList[i]
// do something
}
答案 0 :(得分:1)
你无法进行类型转换,因为sortedArrayUsingDescriptors
返回一个NSArray,你需要将该数组中的所有元素复制到Swift Typed数组中。
func getOrderedWaypoints() -> [OrderWaypoint] {
let nameDescriptor = NSSortDescriptor(key: "stop_number", ascending: true)
let sorted = [OrderWaypoint]()
for elem in self.waypoints.sortedArrayUsingDescriptors([nameDescriptor]) {
sorted.append(elem)
}
return sorted
}
答案 1 :(得分:0)
我不会在内存中进行所有排序,而是通常会使用这些辅助方法来获取相关数据直接从数据库中获取数据,如:
var orderedWayPoints: [WayPoint] {
let request = NSFetchRequest(entityName: "Waypoint")
request.sortDescriptors = NSSortDescriptor(key: "stop_number", ascending: true)
request.predicate = NSPredicate(format: "parent = %@", self)
return try! managedObjectContext.executeFetchRequest(request)
}
关键是我通常希望数据库执行排序我的数据而不是代码的繁重工作。而且代码也不多。
答案 2 :(得分:0)
最可能的原因是错误是正确的:self.waypoints
中至少有一个元素实际上不是OrderWaypoint
。你可能有其他类型的响应相同的消息。你可能有一个超级类OrderWaypoint
(你使用的是mogenerator吗?这些实际上是_OrderWaypoint
对象中的任何一个吗?)你是否正在调整这些物体以使它们对它们的真实类型撒谎? KVO可以做到这一点。
在测试目标中失败的事实提高了您嘲笑这些对象的可能性。这可能吗?
我首先仔细检查self.waypoints
的内容,以确保它实际上包含您的想法。
答案 3 :(得分:0)
它仅在您的测试目标中发生的原因是它与您的主应用程序不同,因此您在每个模块中获得OrderWaypoint
类的不同版本,Swift认为这些类是不同的类:App.OrderWaypoint
和AppTest.OrderWaypoint
。
我正在努力在我自己的项目中解决这个问题,并且当我有一个好的解决方案时我会更新:)
更新:对于所有Swift项目,我认为解决方案是从测试目标中删除非测试.swift文件,并将@testable import YourAppModuleName
添加到Swift测试中。显然这是现代的方法,无论如何都应该这样做。 (虽然如果你的应用程序都是Swift,你可能会遇到这个问题。)
这对我来说不起作用,因为我有用Objective-C编写的测试需要访问我的Swift类,而且我很难找到一个Objective-C等价物来导入应用程序目标的Swift模块
我的解决方案是重写Objective-C中的问题代码,它不会进行严格的类型检查。在我的情况下,这很容易,因为有问题的函数是在最初在Objective-C中声明的类的扩展中,因此很容易将它们移动。
更新2:稍微改进但更简单的解决方案是从测试目标中删除应用Swift文件,然后将测试目标中的标头搜索路径设置为指向{{1}来自 app 目标的文件夹,并在需要它的Objective-C测试中包含DerivedSources
文件,而不是不再具有应用程序Swift类的App-Swift.h
文件因为你刚从测试目标中删除它们。