首页 > 解决方案 > 带有函数参数的 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)}

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

任何指导将不胜感激。

标签: iosswiftcore-datanspredicatecllocation

解决方案


对于其他在类似问题上苦苦挣扎的人的额外观察。

考虑到上面 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 时填充的。


推荐阅读