带有函数参数的核心数据谓词



>我试图在谓词定义中包含函数。这可能吗?

假设您有一个"地点"的核心数据实体,其属性为 纬度和经度。

我想在与用户位置的指定距离。当然,我可以遍历整个数据库并计算每个地方和 用户位置,但我将有大约 35000 个位置,看起来 在 fetchedResultsController setup.

我尝试了下面的代码,但我收到一条错误消息"问题 subpredicate BLOCKPREDICATE(0x2808237b0) with userInfo of (null)">

func myDistanceFilter(myLat : CLLocationDegrees, myLong : CLLocationDegrees, cdLat : CLLocationDegrees, cdLong : CLLocationDegrees) -> Bool {
let myLocation = CLLocation(latitude: myLat, longitude: myLong)
let cdLocation = CLLocation(latitude: cdLat, longitude: cdLong)
if myLocation.distance(from: cdLocation) < 5000.0 {
return true
} else {
return false
}
}//myDistancePredicate

在 fetchedResultsController 中:

let distancePredicate = NSPredicate {_,_ in self.myDistanceFilter(myLat: 37.774929, myLong: -122.419418, cdLat: 38.0, cdLong: -122.0)}

如果可以在谓词中包含块/函数,如何获取对正在评估的实体对象的属性的引用?

任何指导将不胜感激。

对于其他遇到类似问题的人的额外观察。

考虑到上面pbasdf和Jerry的建议,至少就我而言,没有理由为什么一个区域必须是圆形的。我将制作一个名称,表示一个近乎矩形的区域。我用纬度和经度值运行了一些测试。这些纬度和经度值可以缩放为包含用户指定的圆形半径的矩形。一度纬度约为 69 英里,芝加哥纬度的一度经度约为 51 英里。我使用了以下内容:

var myUserLatitude : CLLocationDegrees!
var myUserLongitude : CLLocationDegrees!

在视图的初始化文件中:

guard let userLatitude = locationManager.location?.coordinate.latitude else {return}
guard let userLongitude = locationManager.location?.coordinate.longitude else {return}
myUserLatitude = userLatitude
myUserLongitude = userLongitude

在 fetchedResultsController 变量创建中:

let latitudeMinPredicate = NSPredicate(format: "latitude >= %lf", myUserLatitude - 1.0)
let latitudeMaxPredicate = NSPredicate(format: "latitude <= %lf", myUserLatitude + 1.0)
let longitudeMinPredicate = NSPredicate(format: "longitude >= %lf", myUserLongitude - 1.0)
let longitudeMaxPredicate = NSPredicate(format: "longitude <= %lf", myUserLongitude + 1.0)
var compoundPredicate = NSCompoundPredicate()
compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [anotherUnrelatedPredicate,latitudeMinPredicate,latitudeMaxPredicate,longitudeMinPredicate, longitudeMaxPredicate])
fetchRequest.predicate = compoundPredicate        

显然,我将创建另一个属性来缩放每个用户所需区域的 1.0 值。最初的测试似乎有效,最重要的是,我简直不敢相信它有多快。从字面上看,表视图由 viewController 切换到封闭地图视图时填充。

嗯,是的,这是可能的NSPredicate确实有+predicateWithBlock:init(block:)

但是,如果您在该页面上向下滚动,您会看到坏消息:

Core Data 在内存中和原子存储中支持基于块的谓词,但在基于 SQLite 的存储中不支持。

因此,无论是使用内存中存储,还是在代码中进行筛选,无论哪种方式,都需要将这 35,000 个项目放入内存中,并且暴力破解方法的性能都会很差。

有一个复杂的点,SQL不再合适 - 你可以通过实际代码获得更好的性能。 我认为你的要求远远超出了这一点。 这将是一个有趣的优化计算机科学项目。 您需要做一些预计算,类似于向数据库添加索引。 请考虑向place实体添加region属性,然后编写谓词以提取目标位置区域内的所有位置和所有直接邻居。 然后在代码中筛选这些候选项。 我相信其他人已经完成了这项工作 - 想想手机网络中的细胞 - 但Core Data不会免费为您提供。

最新更新