Falla de aserción en UICollectionViewData indexPathForItemAtGlobalIndex

Estoy usando performBatchUpdates () para actualizar mi vista de colección, donde estoy haciendo una actualización completa, es decir, eliminar lo que estaba en él y volver a insertlo todo. Las actualizaciones por lotes se realizan como parte de un Observador que se adjunta a un NSMutableArray ( bingDataItems ).

cellItems es la matriz que contiene elementos que se insertán o se insertán en la vista de colección.

Aquí está el código:

 - (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { cultARunner *_cultARunner = [cultARunner getInstance]; if ( [[_cultARunner bingDataItems] count] ) { [self.collectionView reloadData]; [[self collectionView] performBatchUpdates: ^{ int itemSize = [cellItems count]; NSMutableArray *arrayWithIndexPaths = [NSMutableArray array]; // first delete the old stuff if (itemSize == 0) { [arrayWithIndexPaths addObject: [NSIndexPath indexPathForRow: 0 inSection: 0]]; } else { for( int i = 0; i < cellItems.count; i++ ) { [arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]]; } } [cellItems removeAllObjects]; if(itemSize) { [self.collectionView deleteItemsAtIndexPaths:arrayWithIndexPaths]; } // insert the new stuff arrayWithIndexPaths = [NSMutableArray array]; cellItems = [_cultARunner bingDataItems]; if ([cellItems count] == 0) { [arrayWithIndexPaths addObject: [NSIndexPath indexPathForRow: 0 inSection: 0]]; } else { for( int i = 0; i < [cellItems count]; i++ ) { [arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]]; } } [self.collectionView insertItemsAtIndexPaths:arrayWithIndexPaths]; } completion:nil]; } } 

Recibo este error, pero no todas las veces (¿por qué?)

 2012-12-16 13:17:59.789 [16807:19703] *** Assertion failure in -[UICollectionViewData indexPathForItemAtGlobalIndex:], /SourceCache/UIKit_Sim/UIKit-2372/UICollectionViewData.m:442 2012-12-16 13:17:59.790 [16807:19703] DEBUG: request for index path for global index 1342177227 when there are only 53 items in the collection view 

Comprobé el único subprocess que mencionó el mismo problema aquí: Error de UICollectionView Assertion , pero no está muy claro, es decir, hacer [collectionview reloadData] no es recomendable en el bloque performBatchUpdates() .

¿Alguna sugerencia sobre lo que podría ir mal aquí?

¡Finalmente! Ok, esto es lo que causó este crash para mí.

Como se señaló anteriormente, estaba creando vistas suplementarias para proporcionar encabezados de sección estilo personalizado para mi vista de colección.

El problema es el siguiente: parece que el path index de una vista complementaria DEBE corresponder al path index de una célula existente en la colección. Si la ruta de índice de la vista suplementaria no tiene una celda ordinaria correspondiente, la aplicación se bloqueará. Creo que la vista de colección intenta recuperar información para la celda de una vista suplementaria por alguna razón durante el procedimiento de actualización. Se bloquea cuando no puede encontrar uno.

Espero que esto solucione tu problema también.

Esta es la solución adecuada para este crash:

Cada una de sus vistas complementarias está asociada a una determinada ruta de índice. Si no tiene una celda en esa ruta de índice (carga inicial, ha eliminado la fila, etc.), devuelva una altura de 0 para su vista suplementaria a través del delegado de su layout.

Entonces, para un layout de flujo, implemente UICollectionViewDelegateFlowLayout's

 (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section 

método (y el método de pie de página correspondiente, si está utilizando pies de página) con la siguiente lógica

 if ( you-have-a-cell-at-the-row-for-this-section ) return myNormalHeaderSize; else return CGSizeMake( 0,0 ); 

¡Espero que esto ayude!

reloadData no funciona para mí, porque todo el propósito de usar performBatchUpdates es get los cambios animados. Si usa reloadData , solo actualizará los datos, pero sin animaciones.

Entonces, las sugerencias de "replace performBatchUpdates con reloadData " dicen que "renunciar a lo que intentas hacer".

Lo siento, estoy frustrado porque este error sigue apareciendo mientras estoy intentando hacer algunas excelentes actualizaciones animadas y mi model es 100% correcto, es que hay algo de magia dentro de iOS que se rompe y me obliga a cambiar mi soluciones por completo

Mi opinión es que las vistas de colección siguen siendo difíciles y no pueden hacer actualizaciones animadas complicadas, aunque deberían poder hacerlo. Porque esto solía ser lo mismo para las vistas de tabla, pero ahora son bastante estables (tomó time, sin embargo).

// Editar (1 de septiembre de 2013) El error reportado está cerrado ahora, por lo que Apple ya resolvió estos problemas.

He estado teniendo el mismo problema.

He intentado varias variaciones, pero la última que parece funcionar es [self.collectionView reloadData] , donde "self.collectionView" es el nombre de la vista de colección.

He probado los siguientes methods, directamente de la "Referencia de class UICollectionView": insert, mover y eliminar elementos.

Estos fueron utilizados al principio, para "mover" el elemento de una sección a otra.

  • deleteItemsAtIndexPaths:

  • insertItemsAtIndexPaths:

A continuación, intenté moveItemAtIndexPath:toIndexPath:

Todos produjeron el siguiente error:

Falla de aserción en – [UICollectionViewData indexPathForItemAtGlobalIndex:], /SourceCache/UIKit_Sim/UIKit-2372/UICollectionViewData.m:442

Por lo tanto, testing el método "reloadData".

Si elimina la última celda de una sección que contiene encabezado / pie de página, aparecerá el error.

Intenté devolver nil para el tamaño / elemento de encabezado / pie de página en ese momento y esto a veces corrige el problema.

Opciones:

  1. Vuelva a cargar la vista de tabla completa en lugar de animar la eliminación del último elemento.
  2. Agregue una celda básica invisible adicional con un tamaño menor a 1.

Un error de bola de queso que puede conducir a este error está reutilizando el mismo UICollectionViewFlowLayout en multiple collectionViews en el mismo viewcontroller! Simplemente inicie diferentes flowLayouts para cada vista de colección y estará listo.

Me encontré con este problema cuando borro una de las celdas de mi vista de colección.

El problema fue que layoutAttributesForElementsInRect un layout personalizado, y el layoutAttributesForElementsInRect la llamada estaba devolviendo más que el número de celdas en la vista de colección después del borrado.

Al parecer, UICollectionView solo recorre la matriz devuelta por el método sin verificar el número de celdas.

La modificación del método para devolver el mismo número de attributes de layout resolvió el locking.

Todavía no podía entender cómo se incrementó tanto el índice global, pero solucioné mi problema insertando un elemento temporal en la matriz de origen de datos subyacente, es decir, cellItems y llamando a [self.collectionview reloadData] en viewDidLoad() .

Esto inserta una celda de marcador de position temporalmente en la vista de colección hasta que active el process real usando performBatchUpdates() .