【问题标题】:insertRowsAtIndexPaths crashes on endUpdates in tableView:willDisplayCell:forRowAtIndexPath only if user scrolls quickly仅当用户快速滚动时,insertRowsAtIndexPaths 在 tableView:willDisplayCell:forRowAtIndexPath 中的 endUpdates 上崩溃
【发布时间】:2011-10-13 07:57:24
【问题描述】:

好的,正如标题所示,当用户滚动到列表底部时,我试图在 uitableview 中插入更多行。整个原因是由于性能原因,使用大型数据集延迟加载数据。

奇怪的是,如果我慢慢滚动,它可以正常工作,但如果我快速滚动,它会在 [tableView endUpdates]; 上崩溃

数据源是一个 nsmutablearray,它使用一个通用的 fetchRequest 从 coredata 加载数据。在我目前的情况下,我无法使用 fetchedResultsController。

调用插入之前和之后的数据源计数是正确的。行数(和数据源数)正确。

如果我慢慢滚动,然后在某个点快速滚动,它会崩溃,通常与索引超出范围相同的错误,但是错误消息中的索引和边界与 tableview 时的原始计数不正确第一次绑定(并且在任何插入发生之前)。即行数为 4,数据源数为 4 等。

这是错误:

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 3 beyond bounds [0 .. 2]'

我也尝试在 cellForRowAtIndexPath 方法中插入行,但结果相同。

有什么想法吗?

【问题讨论】:

    标签: iphone uitableview core-data


    【解决方案1】:

    这不是解决大数据集滚动问题的正确方法。

    1. UITableView 旨在在任何时候仅在内存中保留少量单元格。
    2. 尝试在滚动时获取数据会非常糟糕,因为磁盘访问比 UI 更新慢得多。

    相反,在从 Core Data 获取数据时,您应该考虑限制批量大小。其次,您还应该针对您的应用运行工具并确认热点在哪里。滚动或填充单元格不太可能是慢点。

    顺便说一句,NSMutableArray 在处理来自 Core Data 的结果时很少有用。除非您有特定的理由需要 NSMutableArray,否则您应该将其更改为 NSArray。

    【讨论】:

    • 插入更多行的代码正在从核心数据执行批量加载。表格视图按照正常行为重用单元格,因此内存中的单元格数量不应该成为问题。您认为 nsmutablearray 并不理想,但在这种情况下它是必要的。顺便说一句,我应该提到加载的行数很少,一次 10 行,现有行数是 10。tableview 应该很容易显示。
    • tableview 单元格也只是默认单元格,我什至将单元格文本设置为行索引以查看原因但没有区别。在仪器中,直到应用程序崩溃,我才能看到内存或处理器使用的任何热点。
    • 这又不是正确的方法。加载所有数据,让 Core Data 使用批量大小控制数据流。 Core Data 会给你返回对象引用,但不会加载所有数据,但它会缓存数据,你的应用程序会运行良好。在尝试执行此操作之前,您是否测试过性能?这真的就像逆流而上。我已经看到一个 tableview/coredata 可以毫无问题地处理数千行。
    • 问题在于我不知道表格视图的总行数仅仅从核心数据对象的数量,因为我需要检查每个托管对象的日期属性,然后可能添加更多对象(其中是临时的)在数组中。我正在批量处理日期,并使用谓词来限制目前的批量大小。是的,我事先测试过性能,但它不是最好的,是的,你的权利,tableviews 和核心数据能够处理大量数据(我已经用其他应用程序做过很多次了)。
    • 另一种解决方案是拥有 两个 NSPersistentStore 实例;一个在磁盘上,一个在内存中。当您发现需要添加对象时,然后将它们添加到内存存储中。从那里你可以使用 NSFetchedResultsController 来解决你潜在的内存问题。需要考虑的事情。
    【解决方案2】:

    NSMutableArray 是否在应用程序启动时预填充?目前我假设您使用一个控制器对象作为您的UITableViewDelegate,它只返回最终的行数,而NSMutableArray 在您移动时会被填满?

    在这种情况下,如果您加快滚动速度,从 Core Data 加载可能会太慢,从而导致数组中出现“空洞”。

    【讨论】:

    • 是的,加载视图控制器时会填充 nsmutablearray(仅包含一小批数据),但 nsmutablearray 计数用于当前批次的总行数。当用户滚动并且最后一行变得可见时,将检索另一个批次并将其添加到 nsmutablearray。总数未知,可能是无限的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 1970-01-01
    • 1970-01-01
    • 2013-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多