2

我仍在学习目标 C 和 iOS,但遇到了问题。我正在从包含纬度和经度的 CoreData 创建一个数组。我想获取这个数组并按最近的位置对其进行排序。

这是我到目前为止所拥有的:

NSError *error = nil;
NSFetchRequest *getProjects = [[NSFetchRequest alloc] init];
NSEntityDescription *projectsEntity = [NSEntityDescription entityForName:@"TimeProjects" inManagedObjectContext:context];

[getProjects setEntity:projectsEntity];
projectArray = [[context executeFetchRequest:getProjects error:&error] mutableCopy];

for (NSObject *project in projectArray) {
    // Get location of house
    NSNumber *lat = [project valueForKey:@"houseLat"];
    NSNumber *lng = [project valueForKey:@"HouseLng"];


    CLLocationCoordinate2D coord;
    coord.latitude = (CLLocationDegrees)[lat doubleValue];
    coord.longitude = (CLLocationDegrees)[lng doubleValue];

    houseLocation = [[CLLocation alloc] initWithLatitude:coord.latitude longitude:coord.longitude];
    //NSLog(@"House location: %@", houseLocation);

    CLLocationDistance meters = [houseLocation distanceFromLocation:currentLocation];

}

我也有这个排序代码,但我不确定如何将两者放在一起。

[projectArray sortUsingComparator:^NSComparisonResult(id o1, id o2) {
    CLLocation *l1 = o1, *l2 = o2;

    CLLocationDistance d1 = [l1 distanceFromLocation:currentLocation];
    CLLocationDistance d2 = [l2 distanceFromLocation:currentLocation];
    return d1 < d2 ? NSOrderedAscending : d1 > d2 ? NSOrderedDescending : NSOrderedSame;
}];

有人可以帮助我使这两件事一起工作吗?

4

1 回答 1

6

您的sortUsingComparator块需要CLLocation对象,而不是您的核心数据类的实例。这很容易解决,但我建议的是:

  • 瞬态属性添加currentDistance到您的实体。(瞬态属性不存储在持久存储文件中。)类型应为“Double”。
  • currentDistance获取对象后,计算projectArray.
  • 最后projectArray使用键上的排序描述符对数组进行排序currentDistance

优点是每个物体到当前位置的距离只计算一次,在比较器方法中不重复计算。

代码看起来像这样(未经编译器检查!):

NSMutableArray *projectArray = ... // your mutable copy of the fetched objects
for (TimeProjects *project in projectArray) {
    CLLocationDegrees lat = [project.houseLat doubleValue];
    CLLocationDegrees lng = [project.houseLng doubleValue];
    CLLocation *houseLocation = [[CLLocation alloc] initWithLatitude:lat longitude:lng];
    CLLocationDistance meters = [houseLocation distanceFromLocation:currentLocation];
    project.currentDistance = @(meters);
}
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"currentDistance" ascending:YES]
[projectArray sortUsingDescriptors:@[sort]];

或者,您可以创建实体currentDistance持久属性并在创建或修改对象时计算它。优点是您可以根据currentDistance获取请求添加排序描述符,而不是先获取然后再排序。缺点当然是当当前位置改变时你必须重新计算所有值。

于 2013-08-01T20:12:33.437 回答