uitableviewcontroller uitableviewcell example ios swift uitableview

ios - uitableviewcell - ¿Cómo atrapo el "Índice fuera de rango" en Swift?



uitableviewcell swift (4)

Realmente me gustaría usar un bloque try try clásico más simple en mi código Swift, pero no puedo encontrar nada que lo haga.

Yo solo necesito:

try { // some code that causes a crash. } catch { // okay well that crashed, so lets ignore this block and move on. }

Aquí está mi dilema, cuando TableView se vuelve a cargar con nuevos datos, todavía hay información en la RAM que llama didEndDisplayingCell en una tableView con un origen de datos recién vacío para bloquearse.

Así que frecuentemente arrojé el Index out of range excepción Index out of range

He intentado esto:

func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { do { let imageMessageBody = msgSections[indexPath.section].msg[indexPath.row] as? ImageMessageBody let cell = tableView.dequeueReusableCellWithIdentifier("ImageUploadCell", forIndexPath: indexPath) as! ImageCell cell.willEndDisplayingCell() } catch { print("Swift try catch is confusing...") } }

También he intentado esto:

func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { print(indexPath.section) print(indexPath.row) if msgSections.count != 0 { if let msg = msgSections[indexPath.section].msg[indexPath.row] as? ImageMessageBody { let cell = tableView.dequeueReusableCellWithIdentifier("ImageUploadCell", forIndexPath: indexPath) as! ImageCell cell.willEndDisplayingCell() } } }

Este es un bloque de código de muy baja prioridad, y he perdido mucho tiempo con el método de prueba y error para averiguar qué manejador de errores integrado funciona rápidamente para lo que parecen ser situaciones extremadamente únicas cuando tengo toneladas de escenarios como este donde el código puede bloquearse y no tendrá ningún efecto en la experiencia del usuario.

En resumen, no necesito nada sofisticado, pero Swift parece tener manejadores de errores extremadamente específicos que difieren según si obtengo un valor de un valor de retorno de funciones o un valor del índice de una matriz que puede no existir.

¿Hay un simple intento de detectar Swift como cualquier otro lenguaje de programación popular?


Swift 4:

extension Collection where Indices.Iterator.Element == Index { subscript (exist index: Index) -> Iterator.Element? { return indices.contains(index) ? self[index] : nil } }

Uso :

var index :Int = 6 // or whatever number you need if let _ = myArray[exist: index] { // do stuff }

o

var index :Int = 6 // or whatever number you need guard let _ = myArray[exist: index] else { return }


Como se sugiere en los comentarios y otras respuestas, es mejor evitar este tipo de situaciones. Sin embargo, en algunos casos es posible que desee verificar si un elemento existe en una matriz y si lo devuelve de manera segura. Para esto, puede usar la siguiente extensión de matriz para devolver de forma segura un elemento de matriz.

Swift 3

extension Collection where Indices.Iterator.Element == Index { subscript (safe index: Index) -> Generator.Element? { return indices.contains(index) ? self[index] : nil } }

Swift 2

extension Array { subscript (safe index: Int) -> Element? { return indices ~= index ? self[index] : nil } }

  • De esta manera, nunca alcanzarás el Index out of range
  • Tendrás que comprobar si el artículo es nil

consulte esta pregunta para más

Probar el código Swift3 en un área de juegos en Xcode 8.3.2 todavía conduce a un "bloqueo" cuando dejo ar = [1,3,4], luego dejo v = ar [5]. ¿Por qué? - Thomas Tempelmann 17 de mayo a las 17:40

Debe utilizar nuestro subíndice personalizado para que, en lugar de let v = ar[5] , se let v = ar[safe: 5] .

Valor predeterminado de obtención de la matriz.

let boo = foo[index]

Agregar use el subíndice personalizado.

let boo = fee[safe: index] // And we can warp the result using guard to keep the code going without throwing the exception. guard let boo = foo[safe: index] else { return }


El developer.apple.com/library/ios/documentation/Swift/Conceptual/… de Swift ( do / try / catch ) no es la solución para excepciones de tiempo de ejecución como "índice fuera de rango".

Una excepción de tiempo de ejecución (también puede ver estos llamados trampa , error fatal , falla de aserción , etc.) es un signo de error del programador. Excepto en -Ounchecked compilaciones sin -Ounchecked , Swift generalmente garantiza que bloqueará su programa, en lugar de continuar ejecutándose en un estado incorrecto / indefinido. ¡Este tipo de accidentes pueden surgir de un desenvolvimiento forzado ! , desenvolvimiento implícito, uso indebido de referencias unowned propiedad, operaciones / conversiones de enteros que se desbordan, fatalError() sy precondition() sy assert() s, etc. (Y, desafortunadamente, excepciones de Objective-C).

La solución es simplemente evitar estas situaciones . En su caso, verifique los límites de la matriz:

if indexPath.section < msgSections.count && indexPath.row < msgSections[indexPath.section].msg.count { let msg = msgSections[indexPath.section].msg[indexPath.row] // ... }

(O, como dice rmaddy en los comentarios, ¡investigue por qué ocurre este problema! Realmente no debería suceder en absoluto).


Puedes probar un enfoque diferente para esto. Seguramente funcionará!

if msgSections != nil { for msg in msgSections[indexPath.section] { if msgSections[indexPath.section].index(of: msg) == indexPath.row { (Code) } }