2017-01-22 4 views
-3

Редактировать: Пожалуйста, внимательно прочитайте. Каждый, кто пытался помочь, думает, что я спрашиваю, почему ниль, развернутая факультативно, вызывает крах. Не я. Я пытаюсь определить, почему это было нуль в первую очередь. И спасибо тем, кто пытался помочь! Я ценю это.Быстрые протоколы - Делегат - это нил, вызывающий крах - НЕ о вариантах

новичок вопрос. Я создаю приложение прогноза погоды в рамках обучения программе Swift.

У меня есть протокол передачи местоположения обратно в мой основной класс прогноза для использования для возврата прогноза для определенного места. У меня есть два разных класса, которые используют протокол при возвращении местоположения для возврата прогноза.

У меня возникла проблема, связанная с тем, что один из классов вызовет сбой для разворачивания нуля в отношении делегирования классу прогноза. Другой класс, настроенный с точно такой же функцией возврата, не имел этой ошибки. Я отслеживал сбой до подготовки (для функции segue: в классе прогноза. Поскольку мне не нужно было передавать информацию в один из классов, я не установил destinationViewController.delegate = self для разбившегося класса. Мой вопрос заключается в том, почему я должен был установить это в классе прогноза, чтобы предотвратить разворот нисходящей аварии.

Я знаю, что я что-то пропустил, почему протокол должен быть настроен таким образом, но я могу " Мне кажется, что этот вопрос post относится к моей проблеме, но не отвечает на вопрос «почему», но не отвечает на вопрос «почему», просто «что». Что делает установка destinationVC.delegate = self в классе, который инициирует segue, делает это значение слабый делегат var: ForecastTableViewController! нет?

Спасибо.

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

ForecastTableViewController класс:

class ForecastTableViewController: UITableViewController, CLLocationManagerDelegate, LocationToForecast { 

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 

    getLocationNameAndStoreLocation(latitude: (self.weatherData.locationCoordinates.latitude), longitude: (self.weatherData.locationCoordinates.longitude)) 

    if segue.identifier == "locationViewSegue", let destinationViewController = segue.destination as? LocationViewController { 
     destinationViewController.delegate = self 
     destinationViewController.weatherData = self.weatherData 
     destinationViewController.wxObservationStationsArray = self.wxObservationStationsArray 
     destinationViewController.newCoordinates = self.weatherData.locationCoordinates 
    } else if segue.identifier == "searchPriorLocations", let destinationViewController = segue.destination as? SearchBarTableViewController { 
     destinationViewController.delegate = self 
    } 
} 

LocationViewController класс:

class LocationViewController: UIViewController, CLLocationManagerDelegate, UIGestureRecognizerDelegate, UIPickerViewDataSource, UIPickerViewDelegate { 

    weak var delegate: ForecastTableViewController! 


    override func viewWillDisappear(_ animated: Bool) { 
    super.viewWillDisappear(true) 

    switch coordinateChoice { 
    case currentLocationTrue: newCoordinates = currentLocation 
    case UIPickerTrue: 

     newCoordinates = UIPickerLocation 

    case longPressTrue: newCoordinates = longPressLocation 
    default: break 
    } 

    self.delegate!.returnLocationToForecast(locationToReturn: newCoordinates) 
    performSegueToReturnBack() 
} 

SearchBarTableViewController класс:

class SearchBarTableViewController: UITableViewController, UISearchResultsUpdating, NSFetchedResultsControllerDelegate { 

    weak var delegate: ForecastTableViewController! 


    override func viewWillDisappear(_ animated: Bool) { 
    super.viewWillDisappear(true) 

    if !(newCoordinates.latitude == 0 && newCoordinates.longitude == 0) { 
     self.delegate!.returnLocationToForecast(locationToReturn: newCoordinates) 
    } 

    performSegueToReturnBack() 
} 
+0

См. Информацию об альтернативных вариантах развертывания - http://stackoverflow.com/documentation/swift/247/optionals/913/unwrapping-an-optional#t=201701220215478858772. Всякий раз, когда вы используете!Вы сообщаете компилятору, что переменная должна иметь значение, а если нет, вы получите сбой. Вы должны использовать? Чтобы условно развернуть свою ценность, если она может быть nil – Paulw11

+0

Я не стал спрашивать почему. Я понимаю, что если вы разворачиваете опцию, и она равна нулю, она падает. Мой вопрос больше связан с тем, почему в этом случае это было ноль. Представление, с которого я перехожу, выталкивается в стек при появлении нового представления, поэтому он все еще существует, но делегат равен нулю. Зачем? – Yrb

+0

Потому что, если вы не установили 'destinationViewController.delegate = something' (например,' self'), он будет равен нулю. Затем вы говорите 'self.delegate!', Поэтому он будет разбиваться – Paulw11

ответ

3

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

Потому что вы сказали self.delegate!. Это означает «crash me, если у меня нет делегата». Вы не можете жаловаться, если Swift делает именно то, что вы сказали сделать!

Если вы не хотите сбой, то не говорите, что. Скажем self.delegate?.

+0

Что сказал Мэтт. Думать о ! как оператор «сбой, если нуль», и избегайте его, пока вы не испытаете больше опыта в Swift. –

+1

Иногда вы действительно _do_ хотите сбой, если nil. (Потому что nil будет означать, что в программе есть фатальная ошибка.) Но это, очевидно, не одна из этих ситуаций, так как вы (OP) удивлены тем, что вы рушитесь. – matt

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