【问题标题】:UICollectionView strange crash in iOS 7iOS 7 中的 UICollectionView 奇怪的崩溃
【发布时间】:2013-10-18 11:22:41
【问题描述】:

我在使用 ios 7 的 UICollectionView 中遇到了奇怪的崩溃,当滚动速度非常快时往往会发生这种情况。此处的 Apple Developer Forms 报告了类似问题:https://devforums.apple.com/message/901009#901009

我想知道是否有人遇到过这种情况并找到了修复/解决方法?

我正在使用配置了流布局的基本 UICollection 视图。它是通过网络从 json 数据中填充的。数据周期性变化。当它调用reloadData 方法时。我已经检查以确保始终在主线程上调用 reload 方法,因为我担心我的网络回调之一是在后台线程上回调。 绝对不是这样的。

打开 NSZmobies 时,我在崩溃发生时收到以下日志消息:

*** -[NSIndexPath section]: message sent to deallocated instance 0x218b74c0

我还使用 Zombies 跟踪模板运行了附加到 Instruments 的应用程序,并且能够获得以下堆栈跟踪,详细说明导致崩溃的调用序列。

注意 所有调用都是 iOS 框架级别的调用,而不是我的应用程序调用。

   0 libsystem_malloc.dylib malloc_zone_calloc
   1 libsystem_malloc.dylib calloc
   2 libobjc.A.dylib class_createInstance
   3 libobjc.A.dylib +[NSObject allocWithZone:]
   4 Foundation +[NSIndexPath indexPathWithIndexes:length:]
   5 UIKit +[NSIndexPath(UITableView) indexPathForRow:inSection:]
   6 UIKit -[UICollectionViewFlowLayout _layoutAttributesForItemsInRect:]
   7 UIKit -[UICollectionViewFlowLayout layoutAttributesForElementsInRect:]
   8 UIKit __45-[UICollectionViewData validateLayoutInRect:]_block_invoke
   9 UIKit -[UICollectionViewData validateLayoutInRect:]
  10 UIKit -[UICollectionView layoutSubviews]
  11 UIKit -[UIView(CALayerDelegate) layoutSublayersOfLayer:]
  12 QuartzCore -[CALayer layoutSublayers]
  13 QuartzCore CA::Layer::layout_if_needed(CA::Transaction*)
  14 QuartzCore CA::Layer::layout_and_display_if_needed(CA::Transaction*)
  15 QuartzCore CA::Context::commit_transaction(CA::Transaction*)
  16 QuartzCore CA::Transaction::commit()
  17 QuartzCore CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*)
  18 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
  19 CoreFoundation __CFRunLoopDoObservers
  20 CoreFoundation CFRunLoopRunSpecific
  21 CoreFoundation CFRunLoopRunInMode
  22 GraphicsServices GSEventRunModal
  23 UIKit UIApplicationMain
  24 Mixlr main /Users/saman/Desktop/mixlr-iphone/Mixlr/main.m:14
  25 libdyld.dylib start

【问题讨论】:

标签: ios objective-c crash uikit uicollectionview


【解决方案1】:

如果用户正在主动滚动,则集合正在主动请求单元格和标题。因此,在发生这种情况时,您已经修改了支持数据集并调用了 reloadData,但是有一个窗口,其中数据已更改但 reloadData 尚未发布。

如果正确,则解决方案是创建一个仅在用户不主动滚动时应用的更改集。

同样使用 reloadData 是在小钉子上使用大锤子 - 如果可能,插入、删除或更新单个单元格和视图。

编辑:这种情况与人们使用UITableViews 所遇到的情况非常相似。请注意,reloadData 立即返回 - CollectionView 只是将重新加载排队并安排它在当前 runloop 周期结束时运行(不确定它们是如何执行此操作的,但通过发送 dispatch_async NSLogs,您可以验证它是否确实如此)。

我在我的集​​合视图中看到的是,在活动滚动期间,我在创建单元格时收到主线程消息,然后是重新加载数据调用,然后是当前一组可查看单元格的 didDisplay 委托消息,然后 reloadData 返回,然后它开始要求新的集合(我把它变小了,看看能不能让你崩溃)。

我想我现在可以给你的最好建议是将数据模型更改然后 reloadData 消息打包在一个调度块中,并同时发送所有内容(或在一个方法中完成所有内容。

【讨论】:

  • 谢谢。我的网络请求发生在后台,但我很确定集合视图数据源在 main.js 上更新。如果仅在主线程上更改数据,您所说的会是一个问题吗?
  • 我刚刚对我的 collectionView 进行了测试 - 重新加载数据立即返回。它似乎将更新排队,直到主线程的下一次运行。确实没有经过批准的方法可以知道视图何时完全响应了重新加载数据,因此您可能会发布多个,也没有要求视图在主线程的一次运行中完全更新自身。
猜你喜欢
  • 2013-11-23
  • 2014-01-12
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多