/ / Swift problemy z opcjami - ios, swift

Szybkie problemy z opcjami - ios, swift

Jestem szybkim nowicjuszem i chodzę w kółkopróbowanie uruchomić opcje. Zrobiłem dużo Googlingu, czytałem Apple Docs itp. Ale zmagam się z tym (uproszczonym) fragmentem z mojego 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?)
}
}

Błąd jest Cannot assign value of type "String?!" to type "String" w linii zaznaczonej powyżej. Próbowałem rozpakować to inaczej, ale po prostu nie mogę tego zrozumieć.

Więcej kodu

Nadawca jest niestandardową podklasą UIButton o następującej strukturze:

import UIKit

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

Ustawiłem zmienne jako opcjonalne, ponieważ nie wiem, czy przycisk / nie będzie miał tych właściwości.

Metoda wywoływana po dotknięciu przycisku jest następująca:

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

Wiem, że oprzyrządowanie Swift jest częstą przeszkodą dla początkujących, takich jak ja i jest dużo dokumentów na ich temat, ale nie mogę tego zrozumieć, więc każda pomoc byłaby świetna.

Odpowiedzi:

10 dla odpowiedzi № 1

Istnieją opcje na trzech poziomach:

  • The sender: AnyObject? parametr jest opcjonalny.
  • Wysyłanie dowolnych wiadomości do AnyObject zachowuje się podobnie do opcjonalnego łańcuch i zwraca nieopakowane opcje opcjonalne (porównać Dziwne zachowanie AnyObject Swift).
  • The var urlString: String? właściwość jest opcjonalna.

Aby rozwiązać pierwsze dwa opcje, użyj opcjonalnego wiązania / rzutowania do pliku klasa betonu:

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

Teraz

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

skompilowałaby, ale to jest lepiej obsługiwane z operator zerującego koalescencji:

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

Pamiętaj, że nie ma wymuszonego rozpakowania ! operator już!


3 dla odpowiedzi № 2

Musisz po prostu zrobić coś takiego:

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

Problem w kodzie polega na tym, że destUrl to aŁańcuch, ale nadawca! .UrlString jest opcjonalny. Więc nie możesz przypisać jednego do drugiego, musisz odłożyć opcjonalnie przed przypisaniem go albo wymuś to (z!) Albo niech to zrobi. Polecam, jeśli pozwolisz, ale to zależy od ciebie.


3 dla odpowiedzi nr 3

Ręcznie testujesz ciąg znaków dla nil ale potem zapomnisz go rozwinąć:

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

(Zobacz dodany wykrzyknik.)

Ale rozpakowanie takiego łańcucha jest teraz łatwiejsze:

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

The ?? testy operatora dla zer, rozpakowuje lub zwraca prawą stronę, wszystko w jednym wierszu.