【问题标题】:Why global variable not updating value in swift 3?为什么全局变量不更新 swift 3 中的值?
【发布时间】:2017-05-06 03:57:34
【问题描述】:

这是值所在的类

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 以外的计算变量中设置的默认值,但我可以在weatherDataDownloadfunc 中打印值。我很困惑变量如何因此在 swift 3 中工作。

【问题讨论】:

  • 你在闭包之外调用completed,所以它在下载完成之前被调用。
  • 它应该在哪里?它在weatherDataDownloadfunc
  • 应该是responseJSON闭包内的最后一行
  • 如果我这样做,我会收到错误closure use of non-escaping parameter 'completed' may allow it to escape
  • 是的,您需要将completed 参数声明为@escaping

标签: ios swift global-variables


【解决方案1】:

请参阅以下代码示例中的 cmets。您需要将调用移至“completed()”

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 以便阅读您的代码的人知道闭包将在该函数的生命周期之外继续存在。

【讨论】:

  • 在主要问题中添加了@escaping per cmets
  • 我补充了一些解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-01
  • 2011-12-08
  • 1970-01-01
  • 2020-08-20
相关资源
最近更新 更多