4

我在 Core Data 中有一个地理位置列表(实体名称是“Stops”)。

我想按当前位置对它们进行排序,以便向用户显示附近的位置。我正在使用 NSFetchedResultsController 以便结果可以轻松地显示在 UITableView 中。

我正在使用以下代码来尝试这种排序:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"stop_lat" ascending:YES comparator:^NSComparisonResult(Stops *obj1, Stops *obj2) {
    CLLocation *currentLocation = locationManager.location;

    CLLocation *obj1Location = [[CLLocation alloc]initWithLatitude:[obj1.stop_lat doubleValue] longitude:[obj1.stop_lon doubleValue]];
    CLLocation *obj2Location = [[CLLocation alloc]initWithLatitude:[obj2.stop_lat doubleValue] longitude:[obj2.stop_lon doubleValue]];

    CLLocationDistance obj1Distance = [obj1Location distanceFromLocation:currentLocation];
    CLLocationDistance obj2Distance = [obj2Location distanceFromLocation:currentLocation];

    NSLog(@"Comparing %@ to %@.\n  Obj1 Distance: %f\n  Obj2 Distance: %f",obj1.stop_name, obj2.stop_name, obj1Distance, obj2Distance);

    if (obj1Distance > obj2Distance) {
        return (NSComparisonResult)NSOrderedDescending;
    }

    if (obj1Distance < obj2Distance) {
        return (NSComparisonResult)NSOrderedAscending;
    }

    return (NSComparisonResult)NSOrderedSame;
}];

NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setEntity:[NSEntityDescription entityForName:[Stops entityName] inManagedObjectContext:context]];

frcNearby = [[NSFetchedResultsController alloc]
          initWithFetchRequest:fetchRequest
          managedObjectContext:context
          sectionNameKeyPath:nil
          cacheName:nil];

NSError *error;
BOOL success = [frcNearby performFetch:&error];
if (error) NSLog(@"ERROR: %@ %@", error, [error userInfo]);

但是,我的 NSFetchedResultsController 只是返回按我指定的键(“stop_lat”)排序的所有项目,而不是按用户当前位置排序。

看起来我的比较器块从未被调用过,因为那里的 NSLog 从不打印。

我在这里想念什么?

4

4 回答 4

6

基于 Objective-C 的排序描述符不能用于获取请求。

来自“核心数据编程指南”:

...总而言之,如果您直接执行 fetch,则通常不应将基于 Objective-C 的谓词或排序描述符添加到 fetch 请求中。相反,您应该将这些应用于获取的结果。

于 2012-08-19T15:51:38.130 回答
3

对此的另一种看法是在您的“停止” managedObject 上有一个名为 meanSquared 的属性(可能是 NSDecimalNumber)。

当您的设备 lat/long 移动到足以改变“最近停止”数据时,您将使用均方距离(即 (yourLat-stopLat)^2+(yourLong-stopLong)^2)更新所有“停止”对象,然后只需在您的 sortDescriptor 中使用“meanSquared”。

根据您更新用户位置的次数、停靠点之间的距离和停靠点的数量,这可能是最佳解决方案。

于 2012-11-14T14:14:37.527 回答
1

无论如何,您不能按纬度/经度排序,您需要计算每个点的距离并按此排序。或者获取用户附近的一系列纬度/经度值,获取该子集,为它们计算距离并显示。范围就像用户的纬度 +/- 0.1 度,等等。

于 2012-08-19T19:47:28.573 回答
1

我会推荐以下方法:

请参阅http://www.objc.io/issue-4/core-data-fetch-requests.html的“地理位置谓词”部分

它使用谓词获得近似结果,然后在内存中对它们进行准确排序。

于 2014-07-09T17:38:28.587 回答