ios - 带有函数参数的 CoreData 谓词
问题描述
我试图在谓词定义中包含一个函数。这可能吗?
假设您有一个具有纬度和经度属性的 Places 核心数据实体。
我想在距用户位置指定距离内的那些地方的地图视图中添加注释。当然,我可以遍历整个数据库并计算每个 Place 和用户位置之间的距离,但我将有大约 35000 个位置,而且在 fetchedResultsController 设置中使用谓词似乎更有效。
我尝试了下面的代码,但收到一条错误消息“子谓词 BLOCKPREDICATE(0x2808237b0) 与 (null) 的 userInfo 存在问题”
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 的建议,至少在我的情况下,一个区域没有理由必须是圆形的。我将制作一个名称,表示一个几乎是矩形的区域。我用纬度和经度值进行了一些测试。这些纬度和经度值可以缩放为包含用户指定的圆形半径的矩形。纬度 1 度约为 69 英里,芝加哥纬度的 1 度经度约为 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 值。初步测试似乎有效,最重要的是我无法相信它有多快。从字面上看,tableView 是在 viewController 连接到封闭的 mapView 时填充的。
推荐阅读
- ubuntu - 每 3 小时 cronjob 和每 3+1 小时 cronjob
- javascript - 隐藏/禁用特定图形值的提示音
- javascript - svg.js - 如何从 SVG 文本元素中获取 X 位置
- tensorflow - tensorflow:写入失败,因为无法打开文件
- c# - 使用 DataContractSerializer 从 List<> 继承的序列化类不会序列化对象属性
- html - 使用(焦点)检索输入的值
- elasticsearch - 弹性聚合一个结果
- c# - 如何使该方法在一个列表中使用来自不同表和字段的值填充列表?
- mysql - mysql更新以另一个结尾结尾的值
- azure-cosmosdb - 如果需要 ACID 事务,在 CosmosDB 存储过程中强制延续有什么意义