Vinculação condicional: if let error - o inicializador para vinculação condicional deve ter tipo opcional

120

Estou tentando excluir uma linha de minha fonte de dados e a seguinte linha de código:

if let tv = tableView {

causa o seguinte erro:

O inicializador para ligação condicional deve ter tipo opcional, não UITableView

Aqui está o 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)

Como devo corrigir o seguinte?

 if let tv = tableView {
Del Hinds
fonte
8
como tableViewnão é um valor opcional, não há necessidade de verificar se é nulo ou não. Então você pode usá-lo diretamente, quero dizer, remover isso if let e apenas usar tableViewna função
Eric Qian
Para a posteridade, depois de consertar esse problema, me deparei com variable with getter/setter cannot have an initial value, que foi resolvido simplesmente removendo o bloco restante {} após a inicialização, com esta resposta: stackoverflow.com/a/36002958/4544328
Jake T.

Respostas:

216

if let/ if varligação opcional só funciona quando o resultado do lado direito da expressão é opcional. Se o resultado do lado direito não for opcional, você não pode usar esta encadernação opcional. O objetivo dessa ligação opcional é verificar nile usar apenas a variável se ela não for nil.

No seu caso, o tableViewparâmetro é declarado como o tipo não opcional UITableView. É garantido que nunca será nil. Portanto, a ligação opcional aqui é desnecessária.

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)

Tudo o que temos a fazer é nos livrar do if lete mudar quaisquer ocorrências de tvdentro dele para apenas tableView.

nhgrif
fonte
17

para o meu problema específico, tive que substituir

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

Com

let count = 1
if(count > 0)
    {
        // do something ...
    }
Jacksonkr
fonte
2
A melhor resposta desse cara, veja os comentários stackoverflow.com/a/31039427/2797944
Shauket Sheikh
16

Em um caso em que você esteja usando um tipo de célula personalizado, digamos ArticleCell, poderá obter um erro que diz:

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

Você receberá este erro se sua linha de código for semelhante a esta:

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

Você pode corrigir esse erro fazendo o seguinte:

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

Se você verificar o acima, verá que o último está usando conversão opcional para uma célula do tipo ArticleCell.

Lehlohonolo_Isaac
fonte
No meu caso, eu precisava usaras! ArticleCell?
lilbiscuit
9

O mesmo se aplica a instruções de guarda . A mesma mensagem de erro me leva a este post e responda (obrigado @nhgrif).

O código: imprima o sobrenome da pessoa apenas se o nome do meio tiver menos de quatro 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)!")
}

Até eu declarar a última vez como um parâmetro opcional, eu estava vendo o mesmo erro.

Paul Tader
fonte
4

a ligação da condição deve ter tipo opcional, o que significa que você só pode ligar valores opcionais na instrução 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? {


        }
    }
}

Isso funcionará bem, mas certifique-se de que, ao usar, seja do tipo opcional "?"

Viral Shah
fonte
0

Bem, ainda seria conveniente (sintaticamente) se pudéssemos declarar valores usuais dentro da condição if. Portanto, aqui está um truque: você pode fazer o compilador pensar que há uma atribuição de Optional.some(T)a um valor como este:

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