2

我有一個由NSFetchedResultsController驅動的300單元的collectionview。每隔一段時間,所有的對象都會更新,所以我收到了委託消息,告訴我這樣做,並且我讓集合視圖像tableview一樣處理更新。不幸的是,每次發生這種情況時,它會將主線程鎖定幾秒鐘...我不知道爲什麼。這是我的代碼:UICollectionView鎖定主線程~10秒執行批次更新

-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{ 

    [self.cascadeViewController.collectionView performBatchUpdates:^{ 

    NSLog(@"performingBatchUpdates"); 

    for (NSDictionary *change in self.changes) { 

     [change enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, id obj, BOOL *stop) { 

      NSFetchedResultsChangeType type = [key unsignedIntegerValue]; 

      if (type == NSFetchedResultsChangeInsert) { 

       [self.cascadeViewController.collectionView insertItemsAtIndexPaths:@[obj]]; 

      } else if (type == NSFetchedResultsChangeDelete) { 

       [self.cascadeViewController.collectionView deleteItemsAtIndexPaths:@[obj]]; 

      } else if (type == NSFetchedResultsChangeUpdate) { 

       [self.cascadeViewController.collectionView reloadItemsAtIndexPaths:@[obj]]; 

      } else if (type == NSFetchedResultsChangeMove) { 

       [self.cascadeViewController.collectionView moveItemAtIndexPath:obj[0] toIndexPath:obj[1]]; 

      } 

     }]; 
    } 

    NSLog(@"performingBatchUpdates end"); 

} completion:^(BOOL finished) { 

    NSLog(@"completion"); 

    // TODO: implement 
    // [self configureMessageAndFooterView]; 

}]; 

NSLog(@"end of method"); 

[self.changes removeAllObjects]; 

} 

這是怎麼回事?所有300個同時更新的對象不會在我的應用程序的實際執行過程中不斷髮生,但足以讓我擔心它。我正在使用股票UICollectionViewFlowLayout - 我需要做更多的定製?

+0

你應該分析它。 –

+0

我有 - 它在內部API調用上做了很多工作。它擊中了[UICollectionViewUpdate _computeGaps],並且似乎對NSArrays和indexPath比較進行了很多排序。似乎沒有調用任何可以修改的委託方法,或者我可以替換的UICollectionViewFlowLayout方法。 –

+0

您是否同時解決了這個問題?我在我的collectionview中將600個項目同樣的問題鎖定了主線程20秒! – stefreak

回答

0

我依稀記得以前看過類似的行爲,但我沒有NSFetchedResultsController + UICollectionViewFlowLayout組合的解決方案,因爲我們由於許多問題而停止使用這兩個類。你可能會考慮檢查出我們開源替代方案:

  1. TLIndexPathToolsNSFetchedResultsController的替代品。它提供了一個TLIndexPathController類,它是非常類似於NSFetchedResultsController除了它也與普通陣列的工作原理和它可以做動畫排序的濾波(不像NSFetchedResultsController。有許多樣品的項目,包括一個Core Data之一。
  2. VCollectionViewGridLayout作爲UICollectionViewFlowLayout替換它是一個統一的垂直滾動網格,因此它不像UICollectionViewFlowLayout那樣靈活,但是在大多數情況下,動畫通常要好得多,它會出現粘滯標題(如UITableView標題)。有幾個示例項目可以讓你在UICollectionViewFlowLayoutVCollectionViewGridLayout之間切換以查看改進。

我們有一個類似於網格的集合視圖的iPad應用程序,其中包含大約1000個項目,上述內容爲我們提供了出色的性能和流暢的動畫,使我們的核心數據數據庫在後臺更新。

5

performBatchUpdates:completion:有相同的問題鎖定主線程秒僅在收集視圖中只有〜100個元素。

上我找到了解決問題花費了太多的時間後:保證細胞的大小(通過佈局的itemSize屬性返回在-collectionView:layout:sizeForItemAtIndexPath:或定義)有着不小數值。我通過對計算出的細胞高度應用floor來解決性能問題。

這就是說,我不知道爲什麼這種情況發生。通過查看我們異形運行的堆棧跟蹤,大量時間花費在-[UIViewCollectionViewUpdate _computeGaps]中,這些時間依次調用-[NSArray sortedArrayUsingSelector:]數百甚至數千次(以及CFSortIndexes,__CFSimpleMergeSort ...)。通過對我們的單元格高度使用整數值,sortedArrayUsingSelector被調用的次數少於10次,並且整個過程在幾分之一秒內完成。