ios - 使用具有带 FlowLayout 的 UICollectionView 的单元格滚动 UITableView 时,应用程序崩溃

标签 ios swift uitableview uicollectionview

该应用程序是使用 Xcode 7.3.1 在 Swift 2.2 中编写的。

我有一个 UITableView,其中的单元格具有 UICollectionView 和水平 FlowLayout。当我非常快速地上下滚动表格 View 并且不让它在设备(iPad Air 2、iOS 9.3.2)或模拟器上停止时,应用程序崩溃并显示

 EXC_BAD_ACCESS

在 AppDelegate 中。

应用程序未命中在 View Controller 中为 didReceiveMemoryWarning() 设置的断点。

看来代码崩溃了

[UICollectionViewData invalidateItemsAtIndexPaths:]

[_UIFlowLayoutSection computeLayoutInRect:forSection:invalidating:]

其次是

0_dispatch_barrier_async_f_slow.

堆栈跟踪没有指向任何应用代码行。

模拟器的控制台堆栈跟踪(在设备上崩溃时没有控制台堆栈跟踪):

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[_UIFlowLayoutItem frame]: unrecognized selector sent to class 0x110f9ecc0'
*** First throw call stack:
(
0   CoreFoundation                      0x000000011259cd85 __exceptionPreprocess + 165
1   libobjc.A.dylib                     0x00000001137d3deb objc_exception_throw + 48
2   CoreFoundation                      0x00000001125a5c3d +[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3   CoreFoundation                      0x00000001124ebcfa ___forwarding___ + 970
4   CoreFoundation                      0x000000011259e1f8 __forwarding_prep_1___ + 120
5   UIKit                               0x0000000110b1d8b5 -[UICollectionViewData invalidateItemsAtIndexPaths:] + 273
6   UIKit                               0x0000000110ae26b7 -[UICollectionView _invalidateWithBlock:] + 62
7   UIKit                               0x0000000110ae2a6f -[UICollectionView _invalidateLayoutWithContext:] + 656
8   UIKit                               0x0000000110af0ad9 -[UICollectionViewLayout invalidateLayoutWithContext:] + 189
9   UIKit                               0x0000000110afe2cc -[UICollectionViewFlowLayout invalidateLayoutWithContext:] + 604
10  libdispatch.dylib                   0x0000000114257d9d _dispatch_call_block_and_release + 12
11  libdispatch.dylib                   0x00000001142783eb _dispatch_client_callout + 8
12  libdispatch.dylib                   0x00000001142601ef _dispatch_main_queue_callback_4CF + 1738
13  CoreFoundation                      0x00000001124f60f9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
14  CoreFoundation                      0x00000001124b7b99 __CFRunLoopRun + 2073
15  CoreFoundation                      0x00000001124b70f8 CFRunLoopRunSpecific + 488
16  GraphicsServices                    0x0000000114bcaad2 GSEventRunModal + 161
17  UIKit                               0x000000011024cf09 UIApplicationMain + 171
18  market-touch                        0x000000010d4cc472 main + 114
19  libdyld.dylib                       0x00000001142ac92d start + 1
20  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

这是 stack trace (略有不同的版本 here )。

为什么会发生这种情况,我能做些什么来防止这种情况发生?

编辑: 根据 Doro的请求,这是我的 cellForRowAtIndexPath:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier(customCellNibName, forIndexPath: indexPath) as! CustomTableViewCell

    //populating cell with data

    return cell 
}

我根本不调用 func setCollectionViewLayout(_ layout: UICollectionViewLayout, animated animated: Bool)

流程布局设置在 IB 中完成。

启用僵尸对象对我帮助不大,如果有的话。这是我得到的堆栈跟踪:

-[NSIndexPath frame]: unrecognized selector sent to instance 0xc000000012de4890
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSIndexPath frame]: unrecognized selector sent to instance 0xc000000012de4890'
*** First throw call stack:
(0x1815f6db0 0x180c5bf80 0x1815fdc4c 0x1815fabec 0x1814f8c5c 0x186fcccc0 0x186f9e688 0x1868de558 0x1868da0a4 0x1869ae9ec 0x1024f9a7c 0x1024f9a3c 0x1024ff4e4 0x1815acd50 0x1815aabb8 0x1814d4c50 0x182dbc088 0x1867b6088 0x1000c9f58 0x1810728b8)
libc++abi.dylib: terminating with uncaught exception of type NSException

编辑 2:

在我的 CustomTableViewCellawakeFromNib() 方法中,我有以下代码:

if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
    layout.estimatedItemSize = CGSizeMake(50, 22)
}

我注意到,如果我将其注释掉,就不会再发生崩溃(尽管有时整个 TableView 会卡住并且无法使用)。但是, Collection View 单元格的大小不正确。比较:right对比wrong .

在 IB 中,Collection View Flow Layout -> Item Size 是 50x22。用于 Collection View 的单元格中有一个按钮,高度限制为 22pt。以下是为 Collection View 单元格设置布局属性的方法:

override func preferredLayoutAttributesFittingAttributes(layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
    let attributes = super.preferredLayoutAttributesFittingAttributes(layoutAttributes)

    button.setTitle(symbol, forState: .Normal)
    button.sizeToFit()

    attributes.frame = button.frame

    return attributes
}

想法是让这些单元格高 22pt,宽度可变(大约 50pt),它们之间的距离相同。我是否可以在不调用代码的情况下实现这一点,当注释掉时,可以防止崩溃?

最佳答案

结帐 this教程。

基本上,这可能会发生,因为 UITableViewCell 的可重用性必不可少。当您滚动 tableView 时,它使用同一组可见单元格,并通过您的 cellForRowAtIndexPath: 方法设置内容。

根据您的实现,UICollectionViewFlowLayout 似乎在特定时间点被释放。我是说,你调用

func setCollectionViewLayout(_ layout: UICollectionViewLayout,
                    animated animated: Bool)

cellForRowAtIndexPath: 中,当您滚动时,新的 UICollectionViewLayout 被分配并设置为单元格内的 collectionView。在 Edit Scheme -> Diagnostics -> Enable Zombie Objects 中启用僵尸对象。检查当前状态的正确性。

很难建议任何工作片段,但作为一个想法,尝试在 uitableviewCell 的 init 方法中设置所有与流布局相关的属性(仅一次)这将避免重新分配:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"CellIdentifier";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (!cell)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        // set your flow layout or other stuff here
    }


    return cell;
}

希望这对您有所帮助。

关于ios - 使用具有带 FlowLayout 的 UICollectionView 的单元格滚动 UITableView 时,应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37485534/

相关文章:

ios - 如何在 Swift 3 中计算或自动调整 UiTableView 的高度

用于特殊 unicode 字符的 iOS5 精美图标(表情符号?)-不是我想要的

swift - 使用#selector后,Swift Button崩溃

ios - 提供的存储桶 : version00-d20e4. appspot.com 与当前实例的存储桶不匹配错误

swift - Xcode 7资源加载中的奇怪错误是不安全的

swift - TabBar 后面的 TableView 内容

具有可重用组件的 Swift UITableViewCell

iphone - 如何在用户滚动时锁定 View

iphone - CustomTableCellView的实现-layoutSubviews需要调用super,NSInternalInconsistencyException

ios - GCDWebserver 监听 HTTP POST