NSPredicate 与 FUNCTION 不工作

Posted

技术标签:

【中文标题】NSPredicate 与 FUNCTION 不工作【英文标题】:NSPredicate With FUNCTION Not Working 【发布时间】:2012-11-08 15:53:57 【问题描述】:

我的谓词不断使我的应用程序崩溃,并显示消息 Unsupported function expression FUNCTION(SELF, "filterDistanceWithLatitude:" , latitude, longitude)。有谁知道如何解决这个问题?

- (void)setUpFetchedResultsController

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"NextTime"]; //Retrieve data for the place entity
    request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]]; //How to sort it
    self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.context sectionNameKeyPath:nil cacheName:nil]; //Puts the data in a NSFetchedResultsController which is oddly located in CoreDataTableViewController //Puts the data in a NSFetchedResultsController which is oddly located in CoreDataTableViewController
    self.filtered = self.fetchedResultsController.fetchedObjects;
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"FUNCTION(self, 'filterByDistanceWithLatitude:', latitude, longtitude) > 20"];
    self.filtered = [self.filtered filteredArrayUsingPredicate:predicate];


- (double)filterByDistanceWithLatitude:(NSNumber *)latitude andLongitude:(NSNumber *)longitude

    CLLocationDegrees latitudeCoor = [latitude doubleValue]; //Puts the latitude into a NextTime object.
    CLLocationDegrees longitudeCoor = [longitude doubleValue]; //Puts the longtitude into a NextTime object.

    CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:latitudeCoor longitude:longitudeCoor];
    CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:self.currentLocation.latitude longitude:self.currentLocation.longitude];

    NSNumber *distance = [[NSNumber alloc] initWithDouble:[loc1 distanceFromLocation:loc2]];

    return [distance doubleValue];

【问题讨论】:

【参考方案1】:

(基于 SQL 的)Core Data 存储的获取请求不能使用基于 Objective-C 的谓词或排序描述符。您只能过滤存储在数据库中的属性。

这是“核心数据编程指南”中的相关文档:

Fetching Managed Objects:

您无法使用基于瞬态属性的谓词进行获取 (尽管您可以使用瞬态属性在内存中进行过滤 你自己)。 ...总而言之,但是,如果您直接执行 fetch,您应该 通常不会将基于 Objective-C 的谓词或排序描述符添加到 获取请求。相反,您应该将这些应用于 获取。

Fetch Predicates and Sort Descriptors:

抓取和商店类型之间存在一些交互。 ...另一方面,SQL 存储编译谓词和排序 描述 SQL 并评估数据库本身的结果。 这主要是为了性能,但这意味着评估 发生在非 Cocoa 环境中,因此排序描述符(或 依赖于 Cocoa 的谓词)无法工作。

【讨论】:

那么有没有另一种方法可以使用 NSPredicate 来解决这个问题 @gsapienza:不与获取的结果控制器结合使用。但是您可以获取所有对象(使用NSArray *allObjects = [context executeFetchRequest:...],没有限制谓词),然后将过滤器应用于结果数组(例如NSArray *filteredObjects = [allObjects filteredArrayUsingPredicate:predicate] 为此更新了代码,仍然有同样的错误。我的谓词格式是否正确? @gsapienza:我只在NSExpression 中看到过“FUNCTION(...)”,但在NSPredicate 中没有看到。我会使用基于块的谓词 (predicateWithBlock) 来过滤数组。【参考方案2】:

'filterDistanceWithLatitude:' 应该是'filterByDistanceWithLatitude:'

【讨论】:

以上是关于NSPredicate 与 FUNCTION 不工作的主要内容,如果未能解决你的问题,请参考以下文章

重剑无锋,大巧不工

重剑无锋 大巧不工

CGRect.offsetBy 不工​​作

重剑无锋,大巧不工

SQL 查询 Distinct / Group By 不工​​作

大巧不工-WEB前端设计修炼之道pdf