如何循环遍历 nsfetchedresultcontroller

发布于 2024-09-14 17:40:01 字数 363 浏览 2 评论 0原文

在我的应用程序中,我需要循环遍历核心数据中的所有实体,并且我正在使用 NSFetchedresultcontroller。

我现在正在这样做:

NSArray *tempArray = [[NSArray alloc] initWithArray:self.fetchedResultsController.fetchedObjects];

for (MyClass *item in tempArray)
{
    // do something
}

[tempArray release]; tempArray = nil;

有没有更好的方法可以在不创建 tempArray 的情况下做到这一点?

多谢

in my app I need loop through all my entities in Core Data and I'm using NSFetchedresultcontroller.

I'm doing it like this at the moment:

NSArray *tempArray = [[NSArray alloc] initWithArray:self.fetchedResultsController.fetchedObjects];

for (MyClass *item in tempArray)
{
    // do something
}

[tempArray release]; tempArray = nil;

Is there any better way to do it without creating the tempArray?

Thanks a lot

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

余生共白头 2024-09-21 17:40:01

取决于你想做什么。如果您只是更改一个值,那么是的,有一种更简单的方法:

[[[self fetchedResultsController] fetchedObjects] setValue:someValue forKey:@"someKey"]

它将循环遍历设置该值的所有对象。这是标准的 KVC 操作。请注意,这将扩展内存,因为每个实体都会在突变过程中被实现。

如果您需要对每个实体做更多的事情或者遇到内存问题,那么事情会变得更加复杂。注意:在编码优化阶段之前不要担心内存。内存问题的预优化,尤其是核心数据,是浪费你的时间。

这个概念是您将循环每个实体并根据需要更改它。此外,在某个时刻,您应该保存上下文,重置它,然后耗尽本地自动释放池。这将减少您的内存使用量,因为您将在拉入下一批之前将刚刚操作的对象推回内存。例如:

NSManagedObjectContext *moc = ...;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSInteger drainCounter = 0;
for (id object in [[self fetchedResultsController] fetchedObjects]) {
  //Do your magic here
  ++drainCounter;
  if (drainCounter = 100) {
    BOOL success = [moc save:&error];
    NSError *error = nil;
    NSAssert2(!success && error, @"Error saving moc: %@\n%@", [error localizedDescription], [error userInfo]);
    [moc reset];
    [pool drain], pool = nil;
    pool = [[NSAutoreleasePool alloc] init];
    drainCounter = 0;
  }
}

BOOL success = [moc save:&error];
NSError *error = nil;
NSAssert2(!success && error, @"Error saving moc: %@\n%@", [error localizedDescription], [error userInfo]);
[pool drain], pool = nil;

这将降低内存使用量,但它昂贵!! 每 100 个对象就会访问一次磁盘。仅当您确认内存存在问题后才应使用此功能。

Depends on what you want to do. If you are just changing a value then yes, there is an easier way:

[[[self fetchedResultsController] fetchedObjects] setValue:someValue forKey:@"someKey"]

Which would loop through all of the objects setting the value. This is a standard KVC operation. Note that this will expand memory as each entity will get realized during the mutation.

If you need to do something far more involved with each entity or you are running into a memory issue then things get a bit more complicated. NOTE: Do not worry about memory until the optimization stage of coding. Pre-optimization of memory issues, especially with Core Data, is a waste of your time.

The concept is that you will loop over each entity and change it as needed. In addition, at a certain point you should save the context, reset it and then drain a local autorelease pool. This will reduce your memory usage as you will push the objects you just manipulated back out of memory before you pull the next batch in. For example:

NSManagedObjectContext *moc = ...;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSInteger drainCounter = 0;
for (id object in [[self fetchedResultsController] fetchedObjects]) {
  //Do your magic here
  ++drainCounter;
  if (drainCounter = 100) {
    BOOL success = [moc save:&error];
    NSError *error = nil;
    NSAssert2(!success && error, @"Error saving moc: %@\n%@", [error localizedDescription], [error userInfo]);
    [moc reset];
    [pool drain], pool = nil;
    pool = [[NSAutoreleasePool alloc] init];
    drainCounter = 0;
  }
}

BOOL success = [moc save:&error];
NSError *error = nil;
NSAssert2(!success && error, @"Error saving moc: %@\n%@", [error localizedDescription], [error userInfo]);
[pool drain], pool = nil;

This will keep memory usage down but it is expensive!! You are hitting disk after every 100 objects. This should only be used after you have confirmed that memory is an issue.

噩梦成真你也成魔 2024-09-21 17:40:01

抱歉,我认为答案很明显:

        for (MyClass *item in self.fetchedResultsController.fetchedObjects)
        {
            //do something
        }

这是一种明智的记忆方式吗?

Sorry, I think the answer is obvious:

        for (MyClass *item in self.fetchedResultsController.fetchedObjects)
        {
            //do something
        }

Is it a good way to do it memory-wise?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文