变量不会在闭包之外变化

时间:2015-04-07 05:59:30

标签: swift

var arrayLength:Int = 0 // is equal to 0

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    let urlPath = "http://example.com/json"

    let url = NSURL(string: urlPath)!
    let session = NSURLSession.sharedSession()

    let task = session.dataTaskWithURL(url, completionHandler: {
        data, response, error in

        if (error? != nil) {
            println(error)
        } else {
            var jsonResponse: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil)

            let json = JSON(jsonResponse!)
            self.arrayLength = json["dump"].array?.count as Int!
            println("Second: \(self.arrayLength)") // is equal to 3

            for postIndex in 0...self.arrayLength-1 {
                println(json["dump"][postIndex]["title"])
            }
        }

    })
    task.resume()

    println(arrayLength) // is equal to 0 again

我设置了

var arrayLength:Int = 0

在代码的开头。稍后在viewDidLoad()内部我将其更改为3.当我调用它时,在任务块之外它再次等于0.这里的问题是什么,我做错了什么?

1 个答案:

答案 0 :(得分:3)

是的,您正在更改关闭内的arrayLength var。您正面临的问题只是线程工作的正常方式。

  1. viewDidLoad启动时,您将进入主线程
  2. let task = session.dataTaskWithURL(url, completionHandler: { ...定义了一个尚未执行的新任务
  3. task.resume()在另一个线程上启动此任务。这需要一些时间才能完成。完成后,arrayLength将被更改
  4. 立即在主线程上询问您的arrayLength
  5. 下面:

         println(arrayLength) // is equal to 0 again
    

    不是arrayLength再次等于0 ,你没有给你的任务足够的时间来执行和改变那个值。

    编辑:如果你需要在关闭完成后检查arrayLength ......

    只需创建一个函数并在闭包内调用它。像这样:

    override func viewDidLoad() {
       ...
    
        let task = session.dataTaskWithURL(url, completionHandler: {
            data, response, error in
    
            if (error? != nil) {
                println(error)
            } else {
                var jsonResponse: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil)
    
                let json = JSON(jsonResponse!)
                self.arrayLength = json["dump"].array?.count as Int!
                println("Second: \(self.arrayLength)") // is equal to 3
    
                for postIndex in 0...self.arrayLength-1 {
                    println(json["dump"][postIndex]["title"])
                }
    
                functionToDoSomethingAtTheEndOfTheClosure();
            }
    
        })
        task.resume()
    }
    
    func functionToDoSomethingAtTheEndOfTheClosure() {
      // this is going to be executed at the end of the closure's code
    }