iphone - UITableView dequeueReusableCellWithIdentifier Theory
reuseidentifier (3)
Cuando Apple desarrolló el UITableView
para el primer iPhone, tuvieron un problema de rendimiento al desplazarse por él. Entonces, un ingenioso ingeniero descubrió que la causa de esto era que la asignación de objetos tenía un precio, por lo que se le ocurrió una forma de reutilizar las células.
"La asignación de objetos tiene un costo de rendimiento, especialmente si la asignación debe repetirse en un período breve, por ejemplo, cuando el usuario desplaza una vista de tabla. Si reutiliza celdas en lugar de asignar nuevas, mejora en gran medida el rendimiento de la vista de tabla".
Fuente: Biblioteca de referencia de iOS
Para reutilizar una celda que usas:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Ahora, lo que me pregunto es, ¿qué pasa realmente aquí? ¿Se ve en TableView si hay una celda con ese identificador y simplemente devuelve ese? Bueno, sí, pero si envía una referencia en lugar de asignar y tengo una vista de tabla con, digamos, 4 celdas con el mismo identificador, todo visible. ¿Cómo puede multiplicarse en cuatro instancias sin asignar?
Quiero saber esto porque estoy creando un componente de tipo calendario y todas las celdas tienen la misma estructura que el texto dentro de los cambios. Entonces, si pudiera volver a usar mis celdas de alguna manera en lugar de asignar, creo que podría obtener un mejor rendimiento.
Mi propia teoría es que asigna las cuatro celdas (simplemente porque también tiene). Cuando una celda desaparece de la pantalla, se colocará en la cola de reutilización TableView. Cuando se necesita una nueva celda, se ve en el que si una celda con el mismo identificador está disponible, invoca el método prepareForReuse
en esa celda y se elimina de la cola.
El código para deqeueueReusableCellsWithIdentifier:
se verá más o menos así:
(Tomado de uno de mis propios proyectos donde hago algo similar con vistas / páginas en una vista de desplazamiento paginada)
- (UIView*) dequeueReusablePage
{
UIView* page = [reusablePages_ anyObject];
if (page != nil) {
[[page retain] autorelease];
[reusablePages_ removeObject: page];
}
return page;
}
Por lo tanto, mantiene un NSMutableSet
simple con objetos reutilizables.
Cuando las celdas se desplazan fuera de la pantalla y ya no son visibles, se ponen en este conjunto.
Así que comienzas con un conjunto vacío y el conjunto solo crecerá si en realidad tienes más datos para mostrar y luego se ve en la pantalla.
Se desplazaron las celdas de la parte superior de la pantalla, se colocaron en el conjunto y luego se tomaron para la celda que aparece en la parte inferior de la pantalla.
El objetivo de dequeueReusableCellWithIdentifier
es utilizar menos memoria. si utilizamos 100 celdas en un tableView, entonces necesitamos crear 100 celdas cada vez. Reduce la funcionalidad de la aplicación y puede causar un bloqueo. Para que dequeueReusableCellWithIdentifier
inicialice el número particular de celdas que creamos y las celdas se usarán nuevamente para su posterior procesamiento.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *TableIdentifier = @"YourCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TableIdentifier];
}
ExternalClassTableViewCell *myCell = [[ExternalClassTableViewCell alloc]init];
myCell.MyCellText.text = [tableData objectAtIndex:indexPath.row];
myCell.MyCellImage.backgroundColor = [UIColor blueColor];
return cell;
}
dequeueReusableCellWithIdentifier:
solo devuelve una cell
si se ha marcado como lista para volver a usarse. Es por eso que en casi todos los cellForRowAtIndexPath:
verá algo así como
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (nil == cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
// Do something to cell
return cell;
En efecto, se asignarán suficientes filas para llenar la parte visible de la tableview
(más uno o dos más). A medida que las cells scroll
fuera de la pantalla, se eliminan de la table
y se marcan como listas para su reuse
. A medida que la cola de "celdas disponibles" crece, su línea que solicita una dequeued cell
comienza a obtener una cell
para usar, en ese momento ya no tendrá que asignar más.