gpt4 book ai didi

ios - [UICollectionView setCollectionViewLayout :animated:] 上的错误访问

转载 作者:IT王子 更新时间:2023-10-29 07:50:29 25 4
gpt4 key购买 nike

我的 UICollectionView 出现奇怪的崩溃。崩溃的 UICollectionView 嵌入到另一个 UICollectionView 的 UICollectionView 单元中。

我无法重现该问题,如果内部 UICollectionView 重新初始化,有时似乎会发生这种情况,因为外部 CollectionView 正在重新加载它的单元格。

com.apple.main-thread Crashed0   libobjc.A.dylib     objc_msgSend + 91   UIKit   -[UICollectionViewData _setLayoutAttributes:atGlobalItemIndex:] + 602   UIKit   __45-[UICollectionViewData validateLayoutInRect:]_block_invoke_0 + 6683   UIKit   -[UICollectionViewData validateLayoutInRect:] + 14084   UIKit   -[UICollectionViewData layoutAttributesForElementsInRect:] + 825   UIKit   -[UICollectionView setCollectionViewLayout:animated:] + 16446   MyApp   BSCTopnewsCollectionView.m line 52 -[BSCTopnewsCollectionView setupBSCTopnewsCollectionView]7   MyApp   BSCTopnewsCollectionView.m line 27 -[BSCTopnewsCollectionView setWeakDelegatePointer:]8   Myapp   BSCFrontPageViewController.m line 550 -[BSCFrontPageViewController collectionView:cellForItemAtIndexPath:]9   UIKit   -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:] + 25210  UIKit   -[UICollectionView _updateVisibleCellsNow:] + 267211  UIKit   -[UICollectionView layoutSubviews] + 21412  UIKit   -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 25813  QuartzCore  -[CALayer layoutSublayers] + 21414  QuartzCore  CA::Layer::layout_if_needed(CA::Transaction*) + 46015  QuartzCore  CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 1616  QuartzCore  CA::Context::commit_transaction(CA::Transaction*) + 23817  QuartzCore  CA::Transaction::commit() + 31618  QuartzCore  CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 6019  CoreFoundation  __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 2025  UIKit   UIApplicationMain + 112026  MyApp   main.m line 16 main Exception Type:    EXC_BAD_ACCESSCode:    KERN_INVALID_ADDRESS at 0x158848 

What I'm doing in line 52 in setupBSCTopnewsCollectionView is

BSCInfiniteLayout *infiniteLayout = [[BSCInfiniteLayout alloc] init];    (line 52) self.collectionView.collectionViewLayout = infiniteLayout;



Edit: -[BSCFrontPageViewController collectionView:cellForItemAtIndexPath:]

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
if([collectionView isEqual:self.collectionView])
{
if(indexPath.row == 0) // Header Cell
{
BSCTopnewsCollectionView *cell = [collectionView dequeueReusableCellWithReuseIdentifier:BSCHeaderReuseIdentifier forIndexPath:indexPath];
cell.dataSource = self;
cell.weakDelegatePointer = self;

self.topNewsCollectionView = cell;

return cell;
}
else
{
//create normal cells
}
}
else if ([collectionView isEqual:self.topNewsCollectionView.collectionView])
{
BSCTopNewsHeaderCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:BSCTopNewsCellReuseIdentifier forIndexPath:indexPath];
BSCNews *topnews = [self.topNews objectAtIndex:indexPath.row];

[cell setEntity:topnews];

return cell;
}
}

对那里的方法调用的一些说明:

- (void)setWeakDelegatePointer:(BSCFrontPageViewController *)weakDelegatePointer
{
_weakDelegatePointer = weakDelegatePointer;

[self setupBSCTopnewsCollectionView];
[self.collectionView reloadData];
}

- (void)setupBSCTopnewsCollectionView
{
self.collectionView.delegate = self.weakDelegatePointer;
self.collectionView.dataSource = self.weakDelegatePointer;

BSCInfiniteLayout *infiniteLayout = [[BSCInfiniteLayout alloc] init];


infiniteLayout.delegate = self;

// Setup Layout
self.collectionView.collectionViewLayout = infiniteLayout;
self.collectionView.showsHorizontalScrollIndicator = NO;
self.collectionView.pagingEnabled = YES;

// Register Cells
[self.collectionView registerNib:[UINib nibWithNibName:@"BSCTopNewsHeaderCell" bundle:nil] forCellWithReuseIdentifier:BSCTopNewsCellReuseIdentifier];
}



Edit3:崩溃似乎只发生在特殊情况下。如果应用程序在后台,但仍在内存中并且用户再次打开它。然后它会检查我们的 API 是否有新数据,如果它发现了一些东西就会加载它们并重新加载整个 outer collectionView。那就是崩溃发生的时候。

如果在应用程序运行时重新加载 CollectionView 而不是一开始就在后台,一切都很好。


使设置更加清晰。

最佳答案

首先,将 UICollectionView 拖放到 XIB 中的 ViewController,将 Delegate、数据源连接到 ViewController(这只是主 ViewController)

不要为 1 个 CollectionView 使用 2 个不同的 nib cell,因为你只能注册 1 个 Nib。最好将 DecorationView 用作 HeaderView。创建新类 HeaderView:UICollectionReusableView。这个 UICollectionReusableView 是 UIView 的子类,可以在 UICollectionView 内部与 UICollectionViewCell 一起重用。现在您可以注册这两种类型:

[self.collectionView registerNib:[UINib nibWithNibName:@"MyCell" bundle:nil] forCellWithReuseIdentifier:@"CELL"];
[self.collectionView registerNib:[UINib nibWithNibName:@"HeaderView" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderCell"];

接下来,将另一个 UICollectionView 拖到此 HeaderView 中,并与 HeaderView.h 中的 IBOutlet 连接。这里,最好将Delegate、DataSource设置到这个类中进行控制。还要注册此 CollectionView 将使用的 Nib Cell。在 awakeFromNib 中做,因为你之前注册了 Nib

- (void)awakeFromNib{
[self.topCollectionView registerNib:[UINib nibWithNibName:@"TopCell" bundle:nil] forCellWithReuseIdentifier:@"TopCell"];

[self.topCollectionView setDataSource:self];
[self.topCollectionView setDelegate:self];
}

它会很好地工作,如果你将你的数据源存储在外部,只需创建另一个属性并分配给它,然后在此处用于返回内部数据源。

如果您想知道何时单击 headerView 中的 Cell,请使用 customDelegate 协议(protocol)在单击 HeaderCell 时将委托(delegate)发送到 ViewController。

这是我的代码,希望你能理解并能在这里应用你的数据:

https://github.com/lequysang/gitfiles02/blob/master/CollectionViewWithDecorationView.zip

关于ios - [UICollectionView setCollectionViewLayout :animated:] 上的错误访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18189311/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com