Cuándo usar dequeueReusableCellWithIdentifier vs dequeueReusableCellWithIdentifier: forIndexPath

Hay dos sobrecargas para dequeueReusableCellWithIdentifier y estoy tratando de determinar cuándo debo usar uno frente al otro.

Los documentos de Apple con respecto a la función forIndexPath indican: “Este método usa la ruta de índice para realizar una configuración adicional en función de la posición de la celda en la vista de tabla”.

No estoy seguro de cómo interpretar eso sin embargo?

La diferencia más importante es que forIndexPath: version afirma (se bloquea) si no registró una clase o punta para el identificador. La versión anterior (sin forIndexPath: devuelve nil en ese caso.

Registra una clase para un identificador enviando registerClass:forCellReuseIdentifier: a la vista de tabla. Registra un plumín para un identificador enviando registerNib:forCellReuseIdentifier: a la vista de tabla.

Si crea su vista de tabla y sus prototipos de celda en un guión gráfico, el cargador de guión gráfico se encarga de registrar los prototipos de celda que definió en el guión gráfico.

Sesión 200: Novedades de Cocoa Touch de la WWDC 2012 analiza la (entonces nueva) forIndexPath: versión que comienza alrededor de los 8m30s. Dice que “siempre obtendrás una celda inicializada” (sin mencionar que se bloqueará si no registraste una clase o una punta).

El video también dice que “será el tamaño correcto para esa ruta de índice”. Presumiblemente, esto significa que establecerá el tamaño de la celda antes de devolverla, mirando el propio ancho de la vista de tabla y llamando al método tableView:heightForRowAtIndexPath: su delegado (si está definido). Es por eso que necesita la ruta del índice.

dequeueReusableCellWithIdentifier:forIndexPath: siempre devolverá una celda. O bien usa las celdas existentes o crea una nueva y regresa si no hay celdas.

Mientras, el tradicional dequeueReusableCellWithIdentifier: devolverá una celda si existe, es decir, si hay una celda que se puede reutilizar, devuelve la que devuelve nil. Entonces, debería escribir una condición para verificar también el valor nil .

Para responder a su pregunta, utilice dequeueReusableCellWithIdentifier: cuando quiera admitir iOS 5 y versiones más bajas desde dequeueReusableCellWithIdentifier:forIndexPath solo está disponible en iOS 6+

Referencia: https://developer.apple.com/library/ios/documentation/uikit/reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableView/dequeueReusableCellWithIdentifier:forIndexPath :

Nunca he entendido por qué Apple creó el método más nuevo, dequeueReusableCellWithIdentifier: forIndexPath :. Su documentación sobre ellos no está completa, y es algo engañosa. La única diferencia que he podido discernir entre los dos métodos es que ese método anterior puede devolver cero, si no encuentra una celda con el identificador pasado, mientras que el método más nuevo falla, si no puede regresar Una célula. Se garantiza que ambos métodos devuelvan una celda, si ha establecido el identificador correctamente y la convierte en un guión gráfico. También se garantiza que ambos métodos devuelven una celda si registra una clase o xib y convierte su celda en código o en un archivo xib.

Recomendaría usar ambos si está usando contenido dynamic generado. De lo contrario, su aplicación podría fallar inesperadamente. Puede implementar su propia función para recuperar una celda reutilizable opcional. Si es nil , debe devolver una celda vacía que no sea visible:

Swift 3

 // Extensions to UITableView extension UITableView { // returns nil, if identifier does not exist. // Otherwise it returns a configured cell for the given index path open func tryDequeueReusableCell ( withIdentifier identifier: String, for indexPath: IndexPath) -> UITableViewCell? { let cell = self.dequeueReusableCell(withIdentifier: identifier) if cell != nil { return self.dequeueReusableCell(withIdentifier: identifier, for: indexPath) } return nil } } 

Y la extensión para devolver una celda vacía:

 // Extension to UITableViewCell extension UITableViewCell { // Generates an empty table cell that is not visible class func empty() -> UITableViewCell { let emptyCell = UITableViewCell(frame:CGRect(x:0, y:0, width:0, height:0)) emptyCell.backgroundColor = UIColor.clear return emptyCell } } 

Un ejemplo completo de cómo usarlo:

 import Foundation import UIKit // A protocol is used to identify if we can configure // a cell with CellData protocol ConfigureAbleWithCellData { func configure(_ data: CellData) } class MyCustomTableViewCell : UITableViewCell, ConfigureAbleWithCellData { @IBOutlet weak var title:UILabel! = nil func configure(_ data: CellData) { self.title.text = data.title } } // This actually holds the data for one cell struct CellData { var title:String = "" var reusableId:String = "" } class CosmoConverterUnitTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { // Storage var data = Array>() func loadData() { var section1:[CellData] = [] var section2:[CellData] = [] section1.append(CellData(title:"Foo", reusableId:"cellType1")) section2.append(CellData(title:"Bar", reusableId:"cellType2")) data.append(section1) data.append(section2) } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return data[section].count } public func numberOfSections(in tableView: UITableView) -> Int { return data.count } func tableView( _ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard indexPath.row < data[indexPath.section].count else { fatalError("this can't be") } let cellData = data[indexPath.section][indexPath.row] if let cell = tableView.tryDequeueReusableCell( withIdentifier: cellData.reusableId, for: indexPath) { if let configurableCell = cell as? ConfigureAbleWithCellData { configurableCell.configure(cellData) } else { // cell is not of type ConfigureAbleWithCellData // so we cant configure it. } return cell } // id does not exist return UITableViewCell.empty() } } 

Para abreviar:

dequeueReusableCell(withIdentifier, for) solo funciona con prototipos de celdas. Si intentas usarlo cuando la celda del prototipo está ausente, se bloqueará la aplicación.

Hollemans M. 2016, Lista de verificación del Capítulo 2, IOS Apprentice (5ª Edición). pp: 156.