1

我正在尝试在UITableViewNSFetchedResultsController数据库关联的情况下显示一些 Spot。

问题是我需要按与特定位置的距离(无线电)过滤结果。我读到无法NSPredicate计算距离,因此我通过与坐标的简单比较来获取位置周围区域中的所有点。这给了我一个围绕位置的广场。然后,我想迭代结果fetchedObjects并删除不在区域中的结果。

- (NSFetchedResultsController *)newFetchedResultsControllerWithSearch:(NSString *)searchString{


NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                                                                            managedObjectContext:self.managedObjectContext
                                                                                              sectionNameKeyPath:sectionName
                                                                                                       cacheName:@"Stores"];
aFetchedResultsController.delegate = self;

NSError *error = nil;
if (![aFetchedResultsController performFetch:&error])
{
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

// ITERATE FETCHED OBJECTS TO FILTER BY RADIO


int n = [aFetchedResultsController.fetchedObjects count];
NSLog(@"Square result count: %i",n);

self.footerLabel.text = [NSString stringWithFormat:NSLocalizedString(@"%i Spots", @"%i Spots"),n];

return aFetchedResultsController;

如何aFetchedResultsController在返回之前从 .fetchedObjects 中删除对象?UITableView它会改变like中使用的方法[fetchedResultsController objectAtIndexPath:indexPath]吗?

谢谢

4

5 回答 5

2

不能修改获取结果控制器(FRC) 的结果集。您可以过滤结果,但如果将 FRC 用作表视图的数据源,这将无济于事。

可能的解决方案:

  • 预先计算到当前位置的距离并将距离作为持久属性存储在数据库中。然后您可以直接在 FRC 的 fetch 请求中对距离使用过滤器。当然,最大的缺点是您必须在当前位置发生变化时重新计算距离。

  • 不要使用获取的结果控制器。执行一个抓取请求,将抓取请求的结果根据半径过滤成一个数组,并将这个数组作为表格视图的数据源。这里最大的缺点是您失去了 FRC 的自动更新功能。每次更改半径或其他搜索参数时,您都必须重新加载表格视图。

我知道这两种解决方案都不令人满意,但我认为没有一种方法可以将获取的结果控制器与基于函数的过滤器结合起来。

于 2013-01-15T08:17:35.110 回答
0

执行此操作的正确方法是设置一个包含您的谓词的新获取请求。获取结果控制器fetchRequest是只读的,因此您必须将逻辑放入获取结果控制器本身的延迟初始化中。

if (searchIsActive) {
   fetchRequest.predicate = 
       [NSPredicate predicateWithFormat:
          @"(%K < %@ && %K > %@) && (%K < %@ && %K > %@)",
          @"lat", @(locationLat + limit), @"lat", @(locationLat - limit),
          @"lon", @(locationLon + limit), @"lon", @(locationLon - limit)];
}
else { fetchRequest.predicate = nil; }

然后,要更新表,只需将控制器设置为 nil 并重新加载

self.fetchedResultsController = nil;
[self.tableView reloadData];
于 2013-01-15T07:45:53.697 回答
0

地理哈希。

所以它是一个字符串,它有一个位置,您可以在其中执行“喜欢”SQL 查询并在某个区域周围获取结果。

来自维基百科“Geohash 是由 Gustavo Niemeyer 发明并置于公共领域的地理编码系统。它是一种分层空间数据结构,可将空间细分为网格形状的桶,这是所谓的 Z-阶曲线,通常是空间填充曲线。

Geohashes 提供了任意精度等属性,以及逐渐从代码末尾删除字符以减小其大小(并逐渐失去精度)的可能性。

由于精度逐渐下降,附近的地方经常(但不总是)出现相似的前缀。共享前缀越长,两个地方就越接近。”

于 2016-10-06T20:13:41.487 回答
0

使用你 fetchedResultController

NSError *error;

    if (filter) { // check if you need to filter
        // set predicate to self.fetchedResultController.fetchRequest
        self.fetchedResultController.fetchRequest.predicate = [NSPredicate predicateWithFormat:@"your filter params"]];
    }else{ 
        // if you dont need to filter and you need to show all objects set predicate to nil
        self.fetchedResultController.fetchRequest.predicate = nil;
    }

    // and perform fetch!
    if (![self.fetchedResultController performFetch:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    }

之后不要忘记更新用户界面perFormFetch

于 2015-11-05T17:03:19.923 回答
-1

使用NSPredicate搜索/过滤数组。

例子:

NSString *modelName = @"honda";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"model == %@", modelName];
NSArray *filteredArray = [results filteredArrayUsingPredicate:predicate];
于 2013-01-15T06:57:35.537 回答