iOS 7中的UICollectionView奇怪崩溃

Sab*_*bin 9 crash objective-c uikit ios uicollectionview

我在使用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
Run Code Online (Sandbox Code Playgroud)

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

请注意, 所有调用都是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
Run Code Online (Sandbox Code Playgroud)

Dav*_*d H 7

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

如果正确,则解决方案是创建仅在用户未主动滚动时才应用的更改集.

另外使用reloadData在小钉子上使用大锤子 - 如果可能的话插入,删除或更新单个单元格和视图.

编辑:这种情况与人们使用UITableViews时遇到的情况非常相似.请注意,reloadData会立即返回 - CollectionView只会对重新加载进行排队,并将其调度为在当前runloop循环结束时运行(不确定它们是如何执行此操作的,但通过发送dispatch_async NSLog,您可以验证它实际上对它进行了验证).

我在集合视图中看到的是,在活动滚动期间,我在创建单元格时获取主线程消息,然后重新加载数据调用,然后didDisplay委托当前可查看单元格集的消息,然后reloadData返回,然后它开始要求新的设置(我做得更小,看看我是否可以得到你的崩溃).

我想我现在能给你的最佳建议是将数据模型更改包装在一个调度块中,然后在一个调度块中将reloadData消息包起来,并在同一时间发送所有内容(或者在一个方法中完成所有操作).