簡體   English   中英

UICollectionView在unhighlightAllItems上崩潰

[英]UICollectionView crash on unhighlightAllItems

我收到了幾個與iOS 7中的UICollectionView相關的崩潰報告。我無法一致地重新創建這個崩潰。

Exception Type:  SIGSEGV
Exception Codes: SEGV_ACCERR at 0x91c4392b
Crashed Thread:  0

Application Specific Information:
*** Terminating app due to uncaught exception '', reason: ''

Thread 0 Crashed:
0   libobjc.A.dylib                     0x39dd2b26 objc_msgSend + 6
1   UIKit                               0x31fd5eef -[UICollectionView cellForItemAtIndexPath:] + 111
2   UIKit                               0x32060bfd -[UICollectionView _unhighlightItemAtIndexPath:animated:notifyDelegate:] + 149
3   UIKit                               0x32383947 -[UICollectionView _unhighlightAllItems] + 151
4   UIKit                               0x3205f9fb -[UICollectionView touchesBegan:withEvent:] + 367
5   UIKit                               0x31fcb101 forwardTouchMethod + 233
6   UIKit                               0x31fcb101 forwardTouchMethod + 233
7   UIKit                               0x31e3be4b _UIGestureRecognizerUpdate + 5523
8   UIKit                               0x31e73c41 -[UIWindow _sendGesturesForEvent:] + 773
9   UIKit                               0x31e735e7 -[UIWindow sendEvent:] + 667
10  UIKit                               0x31e48a25 -[UIApplication sendEvent:] + 197
11  UIKit                               0x31e47221 _UIApplicationHandleEventQueue + 7097
12  CoreFoundation                      0x2f69e18b __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
13  CoreFoundation                      0x2f69d6e1 __CFRunLoopDoSources0 + 341
14  CoreFoundation                      0x2f69be4f __CFRunLoopRun + 623
15  CoreFoundation                      0x2f606ce7 CFRunLoopRunSpecific + 523
16  CoreFoundation                      0x2f606acb CFRunLoopRunInMode + 107
17  GraphicsServices                    0x342f4283 GSEventRunModal + 139
18  UIKit                               0x31ea8a41 UIApplicationMain + 1137
19  JackThreadsIpad                     0x000922b7 main (main.m:16)

應用程序中的UICollectionViewCells共享一個管理突出顯示的公共超類。 當單元格突出顯示時,alpha會發生變化。

- (void)setHighlighted:(BOOL)highlighted {
    [super setHighlighted:highlighted];

    if (highlighted) {
        self.alpha = 0.8;
    } else {
        self.alpha = 1.0;
    }
}

可以調用[super setHighlighted:highlight]導致這樣的崩潰嗎? 該應用程序是使用XCode 4編譯和提交的,並且僅在iOS 7上發生。還有任何其他建議可以確定這種情況發生的位置。 謝謝你的幫助。

編輯:我能夠在調試器中捕獲它,但它仍然不能始終如一地重現。 崩潰是:

[NSIndexPath section] message sent to deallocated instance XXXXXXXX

如果在用戶拖動視圖時調用reloadData,則可能是原因。

我通過類似的崩潰報告與此相關的崩潰,並通過延遲reloadData調用“修復”問題,直到用戶完成滾動視圖。 例如,創建一個包裝方法,而不是直接調用reloadData。

- (void)updateData {
     if (self.collectionView.isTracking) {
         self.updateDataOnScrollingEnded = YES;
     } else {
         [self.collectionView reloadData];
     }
}

然后當滾動結束時,從滾動視圖的委托方法中調用updateData方法(如果需要)。

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (!decelerate) {
        [self scrollViewStopped:scrollView];
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [self scrollViewStopped:scrollView];
}

- (void)scrollViewStopped:(UIScrollView *)scrollView
{
    if (self.updateDataOnScrollingEnded) {
         [self updateData];
         self.updateDataOnScrollingEnded = NO;
     }
}

我的猜測是在collectionView內部的某個突出顯示的單元格的indexPath上有一個弱引用,而調用reload會釋放該indexPath。 當collectionView嘗試取消突出顯示單元格時,它會崩潰。

編輯:

正如下面的評論所述,這種“解決方案”存在一些缺陷。 在進一步研究這個問題時,似乎在我的情況下,問題與在拖動集合視圖期間在主線程上排隊的多個reloadData調用有關。 當只有一個reloadData調用時,一切都很好,但只要有多個 - 崩潰!

因為我總是在我的collectionView中只有一個部分,所以用。替換了reloadData調用

reloadSections:[NSIndexSet indexSetWithIndex:0]

但是,這會導致細胞快速淡出並再次返回,我通過以下方法避免了這種情況(作為集合視圖上的類別可能會更好)

- (void)reloadCollectionView:(UICollectionView *)collectionView animated:(BOOL)animated
{
    [UIView setAnimationsEnabled:animated];
    [collectionView performBatchUpdates:^{
        [collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
    } completion:^(BOOL finished) {
        [UIView setAnimationsEnabled:YES];
    }];
}

到目前為止,這對我來說效果很好,它還允許在滾動時實際更新數據。

在確定這段代碼后不確定。 但由於崩潰信號(SIGSEGV)似乎是由於內存泄漏造成的。 您只需轉到Xcode設置,然后在Edit Scheme中啟用jsut啟用Zombie選項,然后嘗試重現您的崩潰。 它將顯示方法的控制器類名稱或Xcode控制台內的任何崩潰相關信息。 並且只是嘗試修改您的條件如下: -

- (void)setHighlighted:(BOOL)highlighted {

     //just comment this line or write this line to the below and check
     //[super setHighlighted:highlighted];
    if (highlighted) {
        self.alpha = 0.8;
    } else {
        self.alpha = 1.0;
    }
    [super setHighlighted:highlighted];
}

我有這個問題,但崩潰略有不同。 通過保持任何reloadData來修復,直到高亮顯示被清除。 雖然toostn的建議可以解決這個問題,但是在滾動時能夠重新加載數據是有用的,但在突出顯示時沒有多大意義 - 因為你手指放在一個單元格上。

實現以下UICollectionViewDelegate方法:

- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath {
    self.allowReload = NO;
    return YES;
}


- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath {
    self.allowReload = YES;
    [self reloadIfNecessary]; // calls reloadData if it is necessary to do so!
}

我也在集合視圖中的_unhighlightAllItems中發生了這次崩潰,我使用了長按識別器來改變單元格的狀態(但不是它們的數量),然后調用[collectionView reloadData] 就我而言,來自@toostn的解決方案(使用performBatchUpdates )效果很好。

我還發現使用reloadItemsAtIndexPaths:而不是reloadData也可以避免崩潰。

暫無
暫無

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

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