首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >核心数据: executeFetchRequest与performFetch

核心数据: executeFetchRequest与performFetch
EN

Stack Overflow用户
提问于 2012-09-28 18:44:43
回答 2查看 8.5K关注 0票数 12

我想要一份关于两者比较的详细清单。我知道的事情:

executeFetchRequest

  • 发送给MOC的消息
  • 返回托管对象的数组。
  • 目标:从持久存储中获取对象到MOC
  • 与表视图:与表视图无关
  • 频率:常用于循环中,因此可多次调用。

performFetch

  • 发送给FRC的消息
  • 调用它之后,使用fetchedObjects返回托管对象的数组。
  • 使用表视图: FRC专门用于保持托管对象和表视图行保持同步,并使用performFetch初始化该进程。
  • 频率:通常只有一次。除非FRC的提取请求更改,否则不需要再次调用performFetch

如果我错了,请改正,并附上清单。谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-29 13:16:39

关于executeFetchRequest:

发送给MOC的消息

返回托管对象的数组。

是的,但您也可以更改要检索的结果的类型。在NSFetchRequest中,可以使用以下方法设置不同的结果类型:

代码语言:javascript
复制
- (void)setResultType:(NSFetchRequestResultType)type

其中NSFetchRequestResultType可以是不同类型的。摘自苹果文档:

代码语言:javascript
复制
enum {
   NSManagedObjectResultType        = 0x00,
   NSManagedObjectIDResultType      = 0x01,
   NSDictionaryResultType           = 0x02
   NSCountResultType                = 0x04
};
typedef NSUInteger NSFetchRequestResultType; 

目标:从持久存储中获取对象到MOC

是的,创建NSFetchRequest并执行请求,这与在SQL中创建SELECT语句相同。如果还使用NSPredicate,则与使用SELECT-WHERE语句相同。

与表视图:与表视图无关

是的,但是通过检索到的数据,您可以填充一个表。

频率:常用于循环中,因此可多次调用。

这取决于你想要实现什么。它可能在一个循环中,也可能不在循环中。在循环中执行请求可能会影响性能,但我不担心这一点。核心数据在幕后维护了一种缓存机制。每次执行请求时,如果数据不在缓存中,Core data将在您的存储区(例如sql文件)上执行一次往返旅行,并将其检索的对象填充到缓存中。如果执行相同的查询,由于缓存机制,往返将不会再次执行。无论如何,您可以避免在run循环中执行请求,只需将该请求移出循环。

关于performFetch:

发送给FRC的消息

调用它之后,使用fetchedObjects返回托管对象的数组。

是的,但是如果要在表中填充特定的单元格,也可以使用[_fetchedResultsController objectAtIndexPath:indexPath];检索对象。

在这里,我真的建议阅读一本关于NSFetchedResultsController的好教程

使用表视图: FRC专门用于保持托管对象和表视图行保持同步,并使用performFetch初始化该进程。

是的,NSFetchedResultsControllerNSManagedObjectContext一起为您工作。此外,它还允许延迟加载数据。假设您检索了1000个元素,并且希望在UITableView中显示它们。设置对NSFetchRequest的请求,如:

代码语言:javascript
复制
[fetchRequest setFetchBatchSize:20];

并且将它与NSFetchedResultsController的实例一起使用,它允许首先加载20个元素。然后,当您滚动时,将加载其他20个元素,依此类推。如果没有NSFetchedResultsController,则必须手动实现此行为。有关更多信息,请参阅我提供的教程。

频率:通常只有一次。除非FRC的提取请求更改,否则不需要再次调用performFetch。

这取决于你想要实现什么。大部分时间你都可以叫它一次。

希望这能有所帮助。

编辑

您必须显式地调用performFetch。我喜欢在头文件(.h)中为.h创建一个属性,如下所示

代码语言:javascript
复制
@property (nonatomic, strong, readonly) NSFetchedResultsController* fetchedResultsController;

并将其合成到您的实现文件(.m)中,如

代码语言:javascript
复制
@synthesize fetchedResultsController = _fetchedResultsController;

然后始终在.m文件中重写getter以创建它的新实例:

代码语言:javascript
复制
- (NSFetchedResultsController*)fetchedResultsController
{
    // it already exists, so return it
    if(_fetchedResultsController) return _fetchedResultsController;

    // else create it and return

    _fetchedResultsController = // alloc-init here with complete setup

   return _fetchedResultsController;
}

一旦完成,在类内(例如,在viewDidLoad方法中)使用它如下

代码语言:javascript
复制
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {

    // Handle the error appropriately.
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
票数 16
EN

Stack Overflow用户

发布于 2012-09-28 18:58:04

你在比较错误的元素。NSFetchedResultsController使用NSManagedObjectContext来执行提取,并在适当的配置下监视托管对象上下文中的更改,以验证它正在监视的获取属性的状态,但是实际的获取是由上下文完成的。在这两种情况下,NSManagedObjectContext都会进行提取。不同之处在于,直接使用NSManagedObjectContext可以得到NSArray类型的对象(实际运行时类与使用[NSArray array]的数组不同),而NSFetchedResultsController有不同的用途(有一组结果,并在其获取请求时监视对记录和实体的更改)。换句话说,NSFetchedResultsController使用上下文工作,但它的工作方式与简单的对象集合不同。

注意:您不应该在循环中使用executeFetchRequest,特别是将其称为“多次”。每次获取都有其性能成本。您可以调用executeFetchRequest一次,并执行一个循环来检查结果。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12645641

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档