簡體   English   中英

[UICollectionView setCollectionViewLayout上的錯誤訪問:動畫:]

[英]Bad Access on [UICollectionView setCollectionViewLayout:animated:]

我在UICollectionView中遇到了一個奇怪的崩潰。 崩潰的UICollectionView嵌入在另一個UICollectionView的UICollectionView單元格中。

我無法重現這個問題,有時如果內部UICollectionView得到新的初始化,因為外部CollectionView正在重新加載它的單元格。

com.apple.main-thread Crashed
0   libobjc.A.dylib     objc_msgSend + 9
1   UIKit   -[UICollectionViewData _setLayoutAttributes:atGlobalItemIndex:] + 60
2   UIKit   __45-[UICollectionViewData validateLayoutInRect:]_block_invoke_0 + 668
3   UIKit   -[UICollectionViewData validateLayoutInRect:] + 1408
4   UIKit   -[UICollectionViewData layoutAttributesForElementsInRect:] + 82
5   UIKit   -[UICollectionView setCollectionViewLayout:animated:] + 1644
6   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:] + 252
10  UIKit   -[UICollectionView _updateVisibleCellsNow:] + 2672
11  UIKit   -[UICollectionView layoutSubviews] + 214
12  UIKit   -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 258
13  QuartzCore  -[CALayer layoutSublayers] + 214
14  QuartzCore  CA::Layer::layout_if_needed(CA::Transaction*) + 460
15  QuartzCore  CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 16
16  QuartzCore  CA::Context::commit_transaction(CA::Transaction*) + 238
17  QuartzCore  CA::Transaction::commit() + 316
18  QuartzCore  CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 60
19  CoreFoundation  __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 20
25  UIKit   UIApplicationMain + 1120
26  MyApp   main.m line 16 main 


Exception Type:
    EXC_BAD_ACCESS
Code:
    KERN_INVALID_ADDRESS at 0x158848

我在setupBSCTopnewsCollectionView的第52行中所做的是

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

(line 52) self.collectionView.collectionViewLayout = infiniteLayout;



編輯: - [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]; } 



編輯3 :崩潰似乎只發生在特殊場合。 如果應用程序在后台,但仍在內存中,用戶再次打開它。 然后它檢查我們的API以獲取新數據,如果它發現某些內容將加載它們並重新加載整個外部 collectionView。 這是崩潰發生的時候。

如果在應用程序運行時重新加載CollectionView而不是在開頭的后台,一切都很好。


使設置更清晰一點。

首先,將UICollectionView拖放到XIB中的ViewController,將Delegate,datasource掛鈎到ViewController(這只是主ViewController)

不要為1個CollectionView使用2個不同的筆尖單元格,因為您只能注冊1個筆尖。 最好使用DecorationView作為HeaderView。 創建新類HeaderView:UICollectionReusableView。 這個UICollectionReusableView是UIView的子類,可以與UICollectionViewCell一起在UICollectionView中重用。 現在您可以注冊兩種類型:

[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中執行它是因為之前注冊了NFS

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

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

它會很好用,如果你將數據源存儲在外面,只需創建另一個屬性並分配給它,然后在這里用於返回數據源內部。

如果您想知道何時單擊headerView中的Cell,請在單擊HeaderCell時使用customDelegate協議將委托發送到ViewController。

這是我的代碼,希望您理解並在此處應用您的數據:

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

看起來你的委托或內部集合視圖已經死了(setWeakDelegatePointer:做什么?)。 在模擬器上嘗試Zombies儀器,它應該標記僵屍是否是這種情況。 還為xCode中的所有異常設置“異常斷點”(當從xCode運行應用程序而不是儀器時,將幫助您進行調試)。 還要檢查你的-[BSCFrontPageViewController collectionView:cellForItemAtIndexPath:]實現,它可能會在重用時釋放內部集合視圖。

編輯:為什么不將標題單元格添加為標題而不是單元格0( 此處集合視圖中的標題示例)? 當您為外部集合視圖創建正常單元格時,還要檢查(只是為了確保它不是崩潰的原因)重用標識符。 在模擬器上調試時,還要定期發送mem警告。

另外,為什么要使用標題的另一個集合視圖? 您可以使用與iCarousel類似的內容進行此類布局。

您可以嘗試以下操作,滾動主要的uicollectionview,以便標題不顯示...(更好)然后在模擬器上嘗試執行內存警告...使用硬件 - >模擬內存警告...

這可能應該創建一個單元格回收和刪除(uicollectionview應該銷毀任何現在不重要的東西......如果發生這種情況,標題將被取消分配,你仍然持有一個弱引用...所以你做的任何事情會因為訪問不當而發生...這也是因為缺少內存警告(僅限於您以明確方式創建的內容)而在模擬器上重現“不可能”。

視圖看起來很重,所以你可以嘗試這樣做並發布結果嗎?

從評論中提取我們的“答案”。

可悲的是,沒有一個答案有幫助。 我最終重構了整個事情然后問題消失了。 我甚至與蘋果DTS工程師進行了非常詳細的交談,他也不知道該怎么做。 所以我們只是重構了。 對不起:/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM