2016-06-02 3 views
4

Я быстрый новичок и кружась по кругу, пытаясь получить возможность работать. Я сделал много Googling, читать Apple, Docs и т.д., но я борюсь с этим (упрощенно) фрагмент из моего ViewController:Быстрая проблема с опциями

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    if (segue.identifier == "segueToWebView") { 
     // check what we're passing around 
     print(sender!.urlString) // Optional("http://www.bbc.co.uk") 

     // do some url validation etc 
     var destUrl:String 
     if sender!.urlString == nil{ 
      destUrl = "http://www.google.com" 
     } else { 
      destUrl = sender!.urlString // *** Error here *** 
     } 

     let targetWebViewController:GDWebViewController = segue.destinationViewController as! GDWebViewController 
     targetWebViewController.loadURLWithString(destUrl) 
     targetWebViewController.showsToolbar = true 
     targetWebViewController.title = sender!.busName // this works correctly too (so isn't that a String?) 
    } 
} 

Ошибка Cannot assign value of type 'String?!' to type 'String' на линии, отмеченной выше. Я попробовал разворачивать его по-другому, но просто не могу понять это.

Подробнее Код

Отправитель обычай UIButton подкласс со следующей структурой:

import UIKit 

class TestButton: UIButton { 
    var urlString: String? 
    var busName: String? 
} 

Я поставил переменные быть необязательным, поскольку я не знаю, является ли кнопка будет/не будет иметь этих свойств.

Метод, который вызывается, когда кнопка сливают заключается в следующем:

func tapTap(sender: TestButton) { 
    print(sender.busName, sender.urlString) // Optional("My Button") Optional("http://www.bbc.co.uk") 
    self.performSegueWithIdentifier("segueToWebView", sender: sender) 
} 

Я знаю, что Swift УСТРОЙСТВА является общим камнем преткновения для новичков, как я и есть много документации о них, но я не могу понять так что любая помощь будет большой.

+0

Третья строка в вашем коде 'print (sender! .urlString)' не должна компилироваться, так как 'AnyObject' не имеет члена' urlString'. –

+0

замените 'var destUrl: String' на' var destUrl: String? 'И попробуйте –

+0

Спасибо, ребята, я сейчас в поезде, поэтому проверю ваши предложения как можно скорее и отправьте их обратно. – James

ответ

10

Есть УСТРОЙСТВА на трех уровнях:

  • Параметр sender: AnyObject? является необязательным.
  • Отправка произвольных сообщений в AnyObject ведет себя аналогично факультативно цепочки и возвращает неявно развернутый необязательный (сравните The strange behaviour of Swift's AnyObject).
  • Объект var urlString: String? является необязательным.

Для решения первых двух УСТРОЙСТВА, используйте опциональный связывание/приведение к классу кнопки бетона:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    if (segue.identifier == "segueToWebView") { 
     if let button = sender as? TestButton { 
      // The type of `button` is `TestButton` 
      // ... 
     } 
    } 
} 

Теперь

var destUrl: String 
if button.urlString == nil { 
    destUrl = "http://www.google.com" 
} else { 
    destUrl = button.urlString! 
} 

будет компилировать, но лучше обрабатывается с nil-coalescing operator:

let destUrl = button.urlString ?? "http://www.google.com" 

Обратите внимание, что нет принудительного разворачивания оператора !!

+0

Спасибо за отличный ответ! Я понял, что существует проблема с «optionals in optionals», но никогда не найдет решение без вашей помощи. Я поставил ваш второй кусок кода в 'if let', и он, похоже, работал нормально. Большое спасибо за Вашу помощь. – James

3

Вы просто должны делать что-то вроде этого:

var destUrl:String 
if let durl = sender!.urlString { 
    destUrl = durl 
} else { 
    destUrl = "http://www.google.com" 
} 

Проблемы в коде, что destUrl является строкой, но отправитель .urlString является необязательным!. Поэтому вы не можете назначить их другому. Перед его назначением необходимо развернуть опцию. Либо сила разворачивает его (с!) Либо с помощью if let. Я рекомендую, пусть пусть, но это зависит от вас.

3

Вы вручную тестирует строку для nil, но тогда вы забыли разворачивать его:

var destUrl:String 
if sender!.urlString == nil{ 
    destUrl = "http://www.google.com" 
} else { 
    destUrl = sender!.urlString! 
} 

(См добавляемые восклицательный знак.)

Но разворачивает строку, как это на самом деле более легко, как это:

let destUrl = sender!.urlString ?? "http://www.google.com" 

?? в операторские тесты на ноль, разворачивает или возвращает правую сторону, все в одной строке.

+0

Спасибо за подсказку о ??? оператора - определенно будет удобно в будущем. – James

Смежные вопросы