核心数据:executeFetchRequest vs performFetch

Phi*_*007 12 core-data objective-c nsfetchedresultscontroller nsfetchrequest

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

executeFetchRequest:

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

performFetch:

  • 消息已发送至FRC
  • 调用它之后,用于fetchedObjects返回一个托管对象数组
  • 使用表视图:FRC专门用于保持托管对象和表视图行同步,并用于performFetch初始化该进程.
  • 频率:通常只有一次.除非获取的FRC变化的要求,没有必要要求performFetch第二次

如果我错了请纠正我并附上清单.谢谢.

Lor*_*o B 16

关于 executeFetchRequest:

消息发送给MOC

返回一个托管对象数组

是的,但您也可以更改要检索的结果类型.在NSFetchRequest您可以设置不同的结果类型:

- (void)setResultType:(NSFetchRequestResultType)type
Run Code Online (Sandbox Code Playgroud)

哪里NSFetchRequestResultType可以是不同类型的.取自Apple doc:

enum {
   NSManagedObjectResultType        = 0x00,
   NSManagedObjectIDResultType      = 0x01,
   NSDictionaryResultType           = 0x02
   NSCountResultType                = 0x04
};
typedef NSUInteger NSFetchRequestResultType; 
Run Code Online (Sandbox Code Playgroud)

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

是的,创建NSFetchRequest并执行请求,与在SQL中创建SELECT语句相同.如果你也使用NSPredicate它与使用SELECT-WHERE语句相同.

使用表视图:与表视图无关

是的,但是对于检索到的数据,您可以填充表格

频率:经常在循环中使用,因此可以多次调用

这取决于你想要达到的目标.它可能在一个循环内或没有.在循环中执行请求可能会对性能产生影响,但我不会担心这一点.在引擎盖下,Core Data维护着一种缓存机制.每次执行请求时,如果数据不在缓存中,Core Data会在您的商店(例如sql文件)上执行往返操作,并使用检索到的对象填充缓存.如果执行相同的查询,由于缓存机制,往返将不会再次执行.无论如何,您可以避免在运行循环中执行请求,只需将该请求移出循环.

关于 performFetch:

消息已发送至FRC

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

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

在这里,我真的建议您阅读NSFetchedResultsController上的一个很好的教程

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

是的,一个NSFetchedResultsControllerNSManagedObjectContext你合并的作品.此外,它还可以延迟加载数据.假设您检索了1000个元素,并且希望在a中显示它们UITableView.设置类似的请求NSFetchRequest:

[fetchRequest setFetchBatchSize:20];
Run Code Online (Sandbox Code Playgroud)

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

频率:通常只有一次.除非FRC的获取请求发生更改,否则无需再次调用performFetch

这取决于你想要达到的目标.大多数时候你可以调用一次.

希望有所帮助.

编辑

你必须performFetch明确地打电话.我喜欢NSFetchedResultsController在我的头文件(.h)中创建一个属性

@property (nonatomic, strong, readonly) NSFetchedResultsController* fetchedResultsController;
Run Code Online (Sandbox Code Playgroud)

并在您的实现文件(.m)中合成它

@synthesize fetchedResultsController = _fetchedResultsController;
Run Code Online (Sandbox Code Playgroud)

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

- (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;
}
Run Code Online (Sandbox Code Playgroud)

完成后,在您的课程中(例如在viewDidLoad方法中)使用它

NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {

    // Handle the error appropriately.
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
Run Code Online (Sandbox Code Playgroud)