Enlace condicional: si deja un error, el inicializador para el enlace condicional debe tener un tipo opcional

120

Estoy intentando eliminar una fila de mi fuente de datos y la siguiente línea de código:

if let tv = tableView {

provoca el siguiente error:

El inicializador para el enlace condicional debe tener un tipo opcional, no UITableView

Aquí está el código completo:

// Override to support editing the table view.
func tableView(tableView: UITableView, commitEditingStyle editingStyle:UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {

        // Delete the row from the data source

    if let tv = tableView {

            myData.removeAtIndex(indexPath.row)

            tv.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)

¿Cómo debo corregir lo siguiente?

 if let tv = tableView {
Del Hinds
fuente
8
como tableViewno es un valor opcional, no es necesario comprobar si es nulo o no. Entonces puede usarlo directamente, me refiero a eliminarlo if let y usarlo tableViewen la función
Eric Qian
Para la posteridad, después de que solucioné este problema, me encontré con variable with getter/setter cannot have an initial value, que se resolvió simplemente eliminando el bloque {} sobrante después de la inicialización, con esta respuesta: stackoverflow.com/a/36002958/4544328
Jake T.

Respuestas:

216

if let/ El if varenlace opcional solo funciona cuando el resultado del lado derecho de la expresión es opcional. Si el resultado del lado derecho no es opcional, no puede utilizar este enlace opcional. El objetivo de este enlace opcional es verificar nily solo usar la variable si no es- nil.

En su caso, el tableViewparámetro se declara como tipo no opcional UITableView. Está garantizado que nunca lo será nil. Entonces, el enlace opcional aquí es innecesario.

func tableView(tableView: UITableView, commitEditingStyle editingStyle:UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {
        // Delete the row from the data source
        myData.removeAtIndex(indexPath.row)
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)

Todo lo que tenemos que hacer es deshacernos del if lety cambiar cualquier ocurrencia de tvdentro de él a just tableView.

nhgrif
fuente
17

para mi problema específico tuve que reemplazar

if let count = 1
    {
        // do something ...
    }

Con

let count = 1
if(count > 0)
    {
        // do something ...
    }
Jacksonkr
fuente
2
La mejor respuesta de este tipo, vea los comentarios stackoverflow.com/a/31039427/2797944
Shauket Sheikh
16

En un caso en el que esté utilizando un tipo de celda personalizado, digamos ArticleCell, es posible que obtenga un error que dice:

    Initializer for conditional binding must have Optional type, not 'ArticleCell'

Obtendrá este error si su línea de código se parece a esto:

    if let cell = tableView.dequeReusableCell(withIdentifier: "ArticleCell",for indexPath: indexPath) as! ArticleCell 

Puede corregir este error haciendo lo siguiente:

    if let cell = tableView.dequeReusableCell(withIdentifier: "ArticleCell",for indexPath: indexPath) as ArticleCell?

Si marca lo anterior, verá que este último usa conversión opcional para una celda de tipo ArticleCell.

Lehlohonolo_Isaac
fuente
En mi caso necesitaba usaras! ArticleCell?
lilbiscuit
9

Lo mismo se aplica a las declaraciones de guardia . El mismo mensaje de error me llevó a esta publicación y respuesta (gracias @nhgrif).

El código: Escriba el apellido de la persona solo si el segundo nombre tiene menos de cuatro caracteres.

func greetByMiddleName(name: (first: String, middle: String?, last: String?)) {
    guard let Name = name.last where name.middle?.characters.count < 4 else {
        print("Hi there)")
        return
    }
    print("Hey \(Name)!")
}

Hasta que declaré el último como parámetro opcional, estaba viendo el mismo error.

Paul Tader
fuente
4

La vinculación de condiciones debe tener un tipo optinal, lo que significa que solo puede vincular valores opcionales en la declaración if let

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

    if editingStyle == .delete {

        // Delete the row from the data source

        if let tv = tableView as UITableView? {


        }
    }
}

Esto funcionará bien, pero asegúrese de usar si debe tener el tipo opcional "?"

Shah viral
fuente
0

Bueno, todavía sería conveniente (sintácticamente) si pudiéramos declarar valores habituales dentro de la condición if. Entonces, aquí hay un truco: puede hacer que el compilador piense que hay una asignación de Optional.some(T)a un valor como este:

    if let i = "abc".firstIndex(of: "a"),
        let i_int = .some(i.utf16Offset(in: "abc")),
        i_int < 1 {
        // Code
    }
Artem Ilyumzhinov
fuente