NSFetchRequest 和 predicateWithBlock [英] NSFetchRequest and predicateWithBlock

查看:13
本文介绍了NSFetchRequest 和 predicateWithBlock的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个使用 Core Data 和 NSManagedObjects 来填充 UITableView 的应用程序.我的应用程序中只有一个类,称为 Event.我在 Event 上创建了以下自定义实例方法:

I am playing with an app that uses Core Data and NSManagedObjects to populate a UITableView. There is only one class in my application, called Event. I have created the following custom instance method on Event:

- (BOOL)isExpired {
    return ([[self.endOn dateAtEndOfDay] timeIntervalSinceNow] < 0);
}

我想将显示 Event 对象的 UITableView 限制为仅显示已过期的事件 - 也就是说,isExpired 返回 <代码>是.我试图通过向 NSFetchRequest 添加一个 NSPredicate 来做到这一点:

I would like to limit the UITableView that displays Event objects to only the Events that are expired - that is, where isExpired returns YES. I have tried to do this by adding an NSPredicate to the NSFetchRequest:

NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary * bindings) {return([evaluatedObject isExpired]);}];
[fetchRequest setPredicate:predicate];

但我收到错误:*** 由于未捕获的异常NSInvalidArgumentException"而终止应用程序,原因:子谓词 BLOCKPREDICATE(0x272ac) 的问题"***.这是否意味着您不能将块谓词与 NSFetchRequest 一起使用?还是我只是构造不当?

but I get the error: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Problem with subpredicate BLOCKPREDICATE(0x272ac)' ***. Does this mean that you can't use a block predicate with an NSFetchRequest? Or have I just constructed it improperly?

谢谢!

推荐答案

所以,我们在原帖的评论中似乎已经确定,这可能是由于 SQLite 存储与块谓词不兼容造成的,因为 Core Data无法将这些转换为 SQL 以在商店中运行它们(感谢 JoostK).

So, it appears that we've established in the comments to the original post that this is likely caused by SQLite stores being incompatible with block predicates, since Core Data cannot translate these to SQL to run them in the store (thanks, JoostK).

可能有几种方法可以解决这个问题:

There might be a couple of ways to overcome this:

  • 假设您的实体的结束日期是一个常规属性,您可以将到期约束表示为谓词格式字符串而不是块谓词,Core Data 应该能够将其转换为 SQL 子句.
  • 如果上述可行,您可能更喜欢使用 获取请求模板 以检索过期项目.不过,您需要传入一个替代变量,如 $NOW 以访问当前日期.这具有使谓词模板显示在模型编辑器中的优点.
  • 然而,这两种方法都有重复现有功能(即您的 isExpired 方法)的缺点.因此,另一种方法是首先获取所有符合条件的实体,而不管它们的到期状态如何,然后对结果实体集运行专用过滤步骤以清除未到期的实体.到那时,它们已经从存储中完全复活,您应该能够为此使用块谓词.
  • Provided that the end date of your entities is a regular attribute, you might be able to express the expiry constraint as a predicate format string instead of a block predicate, which Core Data should be able to translate into a SQL clause.
  • If the above is possible, you will probably prefer to use a fetch request template to retrieve the expired items. You would need to pass in a substitution variable like $NOW to give access to the current date, though. This has the advantage of making the predicate template show up in the model editor.
  • Both approaches, however, have the disadvantage of duplicating existing functionality (i.e., your isExpired method). So another way would be fetch all qualifiying entities regardless of their expiry state first, and then run a dedicated filtering step on the resulting set of entities to weed out the non-expired ones. Since by that point, they have been fully resurrected from the store, you should be able to use a block predicate for this.

这篇关于NSFetchRequest 和 predicateWithBlock的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆