为什么全局变量不在swift 3中更新值?

问题描述:

这是其中值是为什么全局变量不在swift 3中更新值?

class CurrentWeather{ 

    var _date:String! 
    var _cityName:String! 
    var _temp:Double! 
    var _weatherType:String! 


    var cityName:String{ 
     if _cityName==nil{ 
      _cityName = "" 
     } 

     return _cityName 
    } 
    var currentTemprature:Double{ 

     if _temp==nil{ 
      _temp = 0.0 
     } 

     return self._temp 
    } 
    var weathertype:String{ 
     if _weatherType==nil{ 
      _weatherType = "" 
     } 
     return _weatherType 
    } 
    var date:String{ 

     if _date==nil{ 
      _date = "" 
     } 
    let dateFormater=DateFormatter() 
     dateFormater.dateStyle = .long 
     dateFormater.timeStyle = .none 
     let currentDate = dateFormater.string(from: Date()) 
     self._date="\(currentDate)" 
     return _date 
    } 


     func weatherDataDownload(completed : downloadComplete){ 
    let weatherUrl=URL(string: constant)! 
    Alamofire.request(weatherUrl , method:.get).responseJSON{response in 

     if let dict=response.result.value as? Dictionary<String,AnyObject>{ 

      if let name=dict["name"] as? String{ 
       self._cityName = name.capitalized 
       print(name.capitalized) 
      } 
      if let weather=dict["weather"] as? [Dictionary<String,AnyObject>]{ 
       if let main=weather[0]["main"] as? String{ 
        self._weatherType=main.capitalized 
        print(main.capitalized) 
       } 

      } 
      if let tempr=dict["main"] as? Dictionary<String,AnyObject>{ 
       if let temp=tempr["temp"] as? Double{ 
        let convertedTemp=Double(round(temp-273.15)) 
        self._temp=convertedTemp 
        print(convertedTemp) 
       } 
      } 

     } 

    } 
    completed() 
}} 

这是的ViewController类

var currentWeatherOj = CurrentWeather() 


    override func viewDidLoad() { 
     super.viewDidLoad() 
     table.delegate=self 
     table.dataSource=self 
     currentWeatherOj.weatherDataDownload { 
      self.updateUIweather() 
     } 


    } 
    func updateUIweather() { 
     weatherType.text=currentWeatherOj.weathertype 
     presentDate.text=currentWeatherOj.date 
     presentLocation.text=currentWeatherOj.cityName 
     presentTemp.text="\(currentWeatherOj.currentTemprature)" 

    } 

当我尝试在ViewController调用其示出了我设定得比计算变量其他的内部的默认值的类_date但我能够在的func内打印值。我很困惑,因为这个,swift 3中的变量是如何工作的。

+0

您在关闭之外调用'completed',因此在下载完成之前调用它。 – Paulw11

+0

它应该在哪里?它在'weatherDataDownload'的'func'里面' – Digs

+0

它应该是'responseJSON'封闭内的最后一行 – Paulw11

请参阅以下代码示例中的注释。您需要将调用“完成()”

func weatherDataDownload(@escaping completed : downloadComplete) { 
    let weatherUrl=URL(string: constant)! 
    Alamofire.request(weatherUrl , method:.get).responseJSON { response in 
     // ... leave your code here alone 

     // put the call to completed() here 
     completed() 
    } 
    // not here 
} 

当你的所有Alamofire,它执行它的在后台线程请求。当该请求完成时,它会调用您定义的闭包(即启动“在...中响应”的闭包)。在完成此操作之前,您不想调用updateUIweather,以便在同一个完成处理程序中将调用“completed()”。

当呼叫completed在该完成处理程序之外时,它将立即被调用......在Alamofire请求被发送之后(但在该后台线程完成之前)立即被调用。完成处理程序中的代码都没有运行,因此您的变量尚未更新。

最后,因为你的completed闭包被传递给一个被发送到后台线程的块,那个闭包“转义”了当前的函数。您添加@escaping,以便读取您的代码的人将知道封闭将超出该函数的生命期。

+0

在主要问题中添加@escaping每个评论 –

+0

它的工作,是否有任何解释? – Digs

+0

我加了一些解释。 –