[英]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.