核心数据 - 在 vi​​ewDidLoad 之前调用数据源方法

Posted

技术标签:

【中文标题】核心数据 - 在 vi​​ewDidLoad 之前调用数据源方法【英文标题】:Core Data - Datasource methods is called before viewDidLoad 【发布时间】:2010-08-14 15:39:57 【问题描述】:

我注意到我的应用程序出现问题是因为UITableView 的Datasource 方法在viewDidLoad 之前被调用。

问题是UITableView 没有正确的行数,它从NSFetchedResultsController 获取行数,但performFetch 的“函数”在viewDidLoad 方法中被调用出于某种原因,它在 Datasource 方法之后被调用。

这里是两个重要方法的来源:

- (void)viewDidLoad 
    [super viewDidLoad];

 self.tableView.allowsSelectionDuringEditing = NO;
 self.tableView.editing = YES;
 self.title = [NSString stringWithFormat:@"%@", [[game valueForKey:@"title"] description]];

    NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error]) 
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    



- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];

我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

正常的程序流程要求在任何UITableView 数据源方法之前调用-viewDidLoad。如果您以相反的顺序获取它们,那么您的代码库中有一些东西导致它们被乱序调用。

首先,在您在这个问题中显示的两种方法中都设置一个断点,并确认它们被无序调用。

然后,查看位于-tableView:numberOfRowsInSection: 断点时的堆栈跟踪,看看为什么它在-viewDidLoad 之前被调用。

更新

-viewDidLoad 肯定会首先被调用,如链接所示。当您在该堆栈跟踪中选择[PlayerViewController -viewDidLoad] 行时,它位于哪一行代码?如果它位于[super viewDidLoad] 上,那么您的超类是什么?在做什么?-viewDidLoad

【讨论】:

断点证实了我的假设。这是-tableView:numberOfRowsInSection: 中的堆栈跟踪:fwdr.org/gt3o。我如何找出它发生的原因? 用另一个查询更新了答案。 您的更新帮助很大,事实证明它位于启用 UITableView 编辑的代码行上(我没有在问题中包含此代码,是的,我知道我应该的)。它将应用程序带到不同的方法,并没有将其返回给-viewDidLoad。我只是通过将有问题的代码行放在方法的末尾来解决问题。 这很有趣,因为当我使用 3.1.3 SDK 时它工作得很好,但现在使用 4.0 SDK 它就不行了。再次感谢您的帮助。【参考方案2】:

在我当前的应用程序中,一般代码流往往是:

(在父控制器中:)

根据父控制器的相关参数构建NSFetchRequest。 使用 NSFetchedResultsController 的 -performFetch: 方法执行提取 如果没有错误,则创建结果视图控制器并将获取的结果控制器与其关联

这种方法可以避免您遇到的问题。也意味着展示结果的视图不需要有搜索逻辑,可以复用展示不同的结果集(虽然传入NSFetchRequest也可以达到同样的结果)。

【讨论】:

这是不必要的。在构建NSFetchedResultsController 之前,您不需要执行提取,这很浪费。此外,-viewDidLoad 在视图出现之前被调用,因此在-viewDidLoad 调用中初始化NSFetchedResultsController 是正常行为。如果您看到不同的行为,则说明有问题。 @Marcus:我没有在“NSFetchedResultsController”构建之前执行提取(通过NSManagedObjectContext -executeFetchRequest?),我不确定你为什么读我这样做。我在上面进行了一些编辑,以使其更加清晰。不过,如果您认为这是浪费还有其他原因,我将不胜感激。

以上是关于核心数据 - 在 vi​​ewDidLoad 之前调用数据源方法的主要内容,如果未能解决你的问题,请参考以下文章

UIButton 在 vi​​ewDidLoad() 中始终为零

CGPointMake 在 vi​​ewDidLoad 中不起作用

情节提要 xib 在 vi​​ewDidLoad 后“卡住”

UIScrollView 在 vi​​ewDidLoad 中调用 setContentSize 后没有更新,但从按钮调用时会更新

我的 tableview 正在注册单元格之前设置数据

表格视图单元格在整数格式时不显示数据