NSFetchRequest 和 predicateWithBlock
我正在玩一个使用 Core Data 和 NSManagedObjects 来填充 UITableView 的应用程序。我的应用程序中只有一个类,称为 Event
。我在 Event
上创建了以下自定义实例方法:
- (BOOL)isExpired {
return ([[self.endOn dateAtEndOfDay] timeIntervalSinceNow] < 0);
}
我想将显示 Event
对象的 UITableView
限制为仅显示已过期的事件- 也就是说,isExpired
返回 YES
。我尝试通过向 NSFetchRequest
添加 NSPredicate
来实现此目的:
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary * bindings) {return([evaluatedObject isExpired]);}];
[fetchRequest setPredicate:predicate];
但收到错误:*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“子谓词 BLOCKPREDICATE(0x272ac) 出现问题” ***
。这是否意味着您不能将块谓词与 NSFetchRequest 一起使用?或者我只是构建不当?
谢谢你!
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);
}
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];
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?
***
Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
因此,我们似乎已经在原始帖子的评论中确定,这可能是由于 SQLite 存储与块谓词不兼容造成的,因为 Core Data 无法将这些谓词转换为 SQL 以在存储中运行它们(感谢 JoostK)。
可能有几种方法可以克服这个问题:
$NOW
才能访问当前日期。这样做的优点是使谓词模板显示在模型编辑器中。isExpired
方法)。因此,另一种方法是首先获取所有合格实体,无论其过期状态如何,然后对结果实体集运行专用过滤步骤以清除未过期的实体。因为到那时,它们已经从商店中完全复活,您应该能够为此使用块谓词。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:
$NOW
to give access to the current date, though. This has the advantage of making the predicate template show up in the model editor.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.您可以在不指定谓词的情况下执行正常的获取请求,然后过滤结果数组:
You can do a normal fetch request without specifying the predicate, and afterwards filter the resulting array: