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 {

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.



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.


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.


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 "?"


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
    }
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.