当从类外部更新时,UILabel在展开Optional值时意外地发现了nil

时间:2016-09-30 02:58:51

标签: swift null uilabel

我正在尝试更新ViewController.swift文件中的temperatureLabel。每当我从Weather类文件中为其赋值时,它都会解决错误:

  

“致命错误:在打开可选值时意外发现nil”。

但是,如果我在ViewController.swift文件的viewdidload中为其赋值,则标签会更新。请帮忙!

class Weather{
var city = ""
var lat = ""
var long = ""
var currentTemp = 0
var currentCondition: String?

var dayOneName: String?
var dayTwoName: String?
var dayThreeName: String?

var dayOneCondition: String?
var dayTwoCondition: String?
var dayThreeCondition: String?

var mainVC: ViewController!


func getWeatherFromAPI(){
    let urlString = "https://api.forecast.io/forecast/<removed key>/(\self.lat),\(self.long)"
    let url = URL(string: urlString)
    URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in
        if error != nil {
            print(error)
        } else {
            do {
                let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:AnyObject]

                    let currentConditions = parsedData["currently"] as! [String:Any]
                    let temp = currentConditions["temperature"] as! Int!
                    self.currentTemp = temp!
                    print(self.currentTemp)//returns expected value

                    self.mainVC.temperatureLabel.text = "\(self.currentTemp)" //fatal error: unexpectedly found nil while unwrapping an Optional value
            } catch let error as NSError {
                print(error)
            }
        }

    }).resume()
}//end of getWeatherFromAPI
}

这是ViewController.swift

class ViewController: UIViewController, CLLocationManagerDelegate {
@IBOutlet weak var conditionImage: UIImageView!

@IBOutlet weak var mainConditionLabel: UILabel!
@IBOutlet weak var mainCityLabel: UILabel!

@IBOutlet weak var temperatureLabel: UILabel!

@IBOutlet weak var dayOneLabel: UILabel!
@IBOutlet weak var dayTwoLabel: UILabel!
@IBOutlet weak var dayThreeLabel: UILabel!
@IBOutlet weak var dayOneConditionImage: UIImageView!
@IBOutlet weak var dayTwoConditionImage: UIImageView!
@IBOutlet weak var dayThreeConditionImage: UIImageView!

let locationManager = CLLocationManager()
var currentLocation = Weather()

override func viewDidLoad() {
    super.viewDidLoad()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()
    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    CLGeocoder().reverseGeocodeLocation(manager.location!, completionHandler: {(placemarks, error)->Void in

        if (error != nil){
            self.locationManager.stopUpdatingLocation()
            print("Reverse geocoder failed with error" + (error?.localizedDescription)!)
            return
        }

        if (placemarks?.count)! > 0{
            let pm = (placemarks?[0])! as CLPlacemark
            self.locationInfo(placemark: pm)
        }
        else{
            print("Problem with the data received from geocoder")
        }
    })
}
func locationInfo(placemark: CLPlacemark?){
    if let containsPlacemark = placemark{
        //stop updating location to save battery life
        //locationManager.stopUpdatingLocation()

        if containsPlacemark.locality != nil{
            let locality = containsPlacemark.locality
            let location = self.locationManager.location
            let lat = String(describing: location!.coordinate.latitude)
            let long = String(describing: location! .coordinate.latitude)

            self.currentLocation.city = locality!
            self.currentLocation.lat = lat
            self.currentLocation.long = long

            self.currentLocation.getWeatherFromAPI()
        }
        else{
            _ = ""
        }
    }
}

}

3 个答案:

答案 0 :(得分:0)

将此添加到viewDidLoad

 self.temperatureLabel.text=Weather.getWeatherFromAPI()

并在你的气象类中删除:

  self.mainVC.temperatureLabel.text = "\(self.currentTemp)"

你要做的另一件事是让func getWeatherFromAPI()返回一个字符串

答案 1 :(得分:0)

尝试

var mainVC: ViewController = ViewController()

答案 2 :(得分:0)

您应该为ViewController分配当前的class ViewController... { override func viewDidLoad() { super.viewDidLoad() ... self.currentLocation.mainVC = self } } 实例。

exit()