Умовне прив'язування: якщо допущена помилка - Ініціалізатор для умовного прив'язки повинен мати необов’язковий тип


120

Я намагаюся видалити рядок із мого джерела даних та наступного рядка коду:

if let tv = tableView {

викликає таку помилку:

Ініціалізатор для умовного прив'язування повинен мати необов’язковий тип, а не UITableView

Ось повний код:

// 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)

Як слід виправити наступне?

 if let tv = tableView {

8
оскільки tableViewне є необов'язковим значенням, не потрібно перевіряти, чи є нульовим чи ні. Таким чином, ви можете безпосередньо використовувати його, я маю на увазі видалити це if let та просто використовувати tableViewу функції
Ерік Цянь

Щодо нащадків, після того як я виправив цю проблему, я зіткнувся з проблемою, variable with getter/setter cannot have an initial valueяку було вирішено шляхом простого видалення блоку залишився {} після ініціалізації, аля ця відповідь: stackoverflow.com/a/36002958/4544328
Джейк Т.

Відповіді:


216

if let/ if varнеобов'язкове прив'язування працює лише тоді, коли результат правої сторони виразу є необов'язковим. Якщо результат правого боку не є необов’язковим, ви не можете використовувати це необов'язкове прив'язування. Суть цього необов'язкового прив’язки полягає в тому, щоб перевірити nilта використовувати змінну лише тоді, коли вона не є nil.

У вашому випадку tableViewпараметр оголошується як необов'язковий тип UITableView. Це гарантовано ніколи не буде nil. Тому необов'язкове прив'язування тут зайве.

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)

Все, що нам потрібно зробити, це позбутися if letі змінити будь-які події tvвсередині нього на справедливі tableView.



16

У випадку, коли ви використовуєте користувацький тип комірок, скажімо ArticleCell, ви можете отримати помилку, яка говорить:

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

Ви отримаєте цю помилку, якщо ваш рядок коду виглядає приблизно так:

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

Ви можете виправити цю помилку, зробивши наступне:

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

Якщо ви перевірте вищесказане, ви побачите, що останній використовує необов'язковий кастинг для комірки типу ArticleCell.


У моєму випадку мені потрібно було скористатисяas! ArticleCell?
lilbiscuit

9

Те саме стосується і заяв охоронців . Це ж повідомлення про помилку приводить мене до цієї публікації та відповіді (спасибі @nhgrif).

Код: Роздрукуйте прізвище людини лише в тому випадку, якщо прізвище менше чотирьох символів.

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)!")
}

Поки я не оголосив останній як необов'язковий параметр, я бачив ту саму помилку.


4

Обв'язка умови повинна мати оптичний тип, що означає, що ви можете прив'язувати необов'язкові значення лише у операторі 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? {


        }
    }
}

Це буде добре, але переконайтесь, що ви використовуєте, якщо нехай він повинен мати оптичний тип "?"


0

Що ж, все-таки було б зручно (синтаксично), якби ми могли оголосити звичайні значення всередині умови if. Отже, ось хитрість: ви можете змусити компілятора думати, що існує присвоєння Optional.some(T)такому значенню:

    if let i = "abc".firstIndex(of: "a"),
        let i_int = .some(i.utf16Offset(in: "abc")),
        i_int < 1 {
        // Code
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.