在视图周围传递Core Data对象时应用程序减速?

时间:2014-05-24 17:31:11

标签: ios performance core-data uitableview nsmanagedobjectcontext

更新:

在仪器上花了很多时间之后,当我切换视图时,我似乎偶然地节省了很多次核心数据。要解决这个问题,我将不得不重新安排大量如何在子视图中的数据输入字段中加载/保存数据。

但是,我确实发现当事件数量增加时导致的主要减速是每个Core Data保存,与Core Data相关的东西正在进行一堆重绘。

看起来这是原始的tableView正在执行[UITableView _updateWithItems:updateSupport]以及随之而来的所有UIKit动画。为了记录,这是一个股票UITableViewController与我的editViewController使用下面的prepareForSeque代码segue。

这是fetchedResultsControllers的作用吗?保持tableView的数据源更新,每次数据更改时tableView都会自行重绘,即使它不再可见?

(我还粘贴了这篇帖子底部的fetchedResultsController的其余代码,这样你就可以看到我如何更新表...再次,这是一个很好的锅炉板的东西,除了一个小修改我在表中添加新项目时做了。)


原始邮件:

在我使用Core Data的iOS应用程序中,我有一个UITableViewController,可正确查询Core Data并显示数据库中存在的“Event”对象(使用fetchedResultsController)。

当我从tableView转到编辑视图时,我会像这样传递所选的数据对象:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"EditEventSegue"]) {
        // start a progress HUD
        [SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeBlack];
        // pass the selected Event object to EditViewController during segue
        NSIndexPath *indexPath = [[self eventListTable] indexPathForSelectedRow];
        Event *theEvent = [_fetchedResultsController objectAtIndexPath:indexPath];
        EditViewController *editController = segue.destinationViewController;
        editController.theEvent = theEvent;
        // set EventListViewController as the delegate for the EditViewController
        editController.delegate = self;
    }
}

editController视图定义了一个属性来保存Event对象:

@property (strong, nonatomic) Event *theEvent;

通过在视图之间传递此对象,所有内容都可以在整个应用程序中运行(有多个视图可以从editController创建/销毁,并且它们也具有相同的theEvent属性定义)。

当我想保存数据时,我已经构建了一个协议,使用委托在视图链上发送“保存”消息(也许这不是最好的方法),原始的tableViewController进行保存(因为它拥有原始的托管对象上下文。)

所有这一切的主要问题是,我发现当我在数据库中有很多Event对象时,切换视图会慢下来!物体越多,它就越慢!我不确定为什么因为我只是传递指向原始tableView中选择的一个Event对象的指针。

是不是因为我在详细视图控制器中将theEvent定义为“强”?每个视图控制器是否只有弱引用?

此外,我已经阅读过关于传递托管对象上下文的内容,但即便如此,我也不确定如何传递对正确对象的引用,而不是我已经这样做了。各种编辑视图控制器(甚至您在上面的代码中看到的单个editController)如何知道正在编辑哪个对象?

任何想法或建议都会有所帮助。谢谢!

编辑:

这是来自包含起始tableView的控制器的代码:

   - (NSFetchedResultsController *)fetchedResultsController {
            if (_fetchedResultsController != nil) {
                return _fetchedResultsController;
            }

            NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
            NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:_managedObjectContext];
            [fetchRequest setEntity:entity];

            NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:YES];
            [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

            [fetchRequest setFetchBatchSize:20];

            NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:_managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
            self.fetchedResultsController = theFetchedResultsController;
            _fetchedResultsController.delegate = self;

            return _fetchedResultsController;
        }

    - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
        // The fetch controller is about to start sending change notifications, so prepare the table view for updates.
        [self.eventListTable beginUpdates];
    }


    - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
        UITableView *tableView = self.eventListTable;
        switch(type) {
            case NSFetchedResultsChangeInsert:
                [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
            case NSFetchedResultsChangeDelete:
                [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
            case NSFetchedResultsChangeUpdate:
                [self configureCell:(EventCell *)[_eventListTable cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
                break;
            case NSFetchedResultsChangeMove:
                [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
        }
    }


    - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
        switch(type) {
            case NSFetchedResultsChangeInsert:
                [self.eventListTable insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
                break;
            case NSFetchedResultsChangeDelete:
                [self.eventListTable deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
                break;
        }
    }


        - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
            // The fetch controller has sent all current change notifications, so tell the table view to process all updates.
            [self.eventListTable endUpdates];

            // if a new event has just been added by the addEvent method then select it and segue to the Edit Details view
            if (_justAddedNewEvent == YES) {
                NSIndexPath *indexPath = [controller indexPathForObject:_newlyAddedEvent];
                _justAddedNewEvent = NO;
                // now open details view of newly added object
                [self.eventListTable selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionBottom];
                [self performSegueWithIdentifier:@"EditEventSegue" sender:self];
            }
        }

0 个答案:

没有答案