2016-03-11 20 views
0

我已經實現了對服務器的URL請求,並使用接收的JSON進行工作。 但我不能解釋的奇怪的事情。爲什麼調試器顯示變量是空的

我的ViewController類:

import UIKit 

class TopRatedViewController: UIViewController { 

    var importedRates: NSArray = [] 
    var successfullyConnected: Bool = true 


    @IBAction func buttonTapped(sender: AnyObject) { 
     print(importedRates) 
    } 


    override func viewDidLoad() { 
     super.viewDidLoad() 

     //MARK: Connection to web service 
     let urlString: String = "http://alma.com/get.php" 

     let url = NSURL(string: urlString) 
     let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration() 
     let session = NSURLSession(configuration: sessionConfig) 
     let task = session.dataTaskWithURL(url!, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in 

      if error != nil { 
       self.successfullyConnected = false 
      }else { 
       var jsonresult = NSArray() 
       do { 
        jsonresult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSArray 
         self.importedRates = jsonresult 
       } catch _ { 
        print("error loading rates") 
       } 
      } 
     }) 

     task.resume() 
     print(importedRates) 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 
} 

所以,如果我跑我的應用程序打印(importedRates)命令打印空數組。在調試窗口中,我看到它沒有任何東西。

但是。如果我點擊那個應該打印這個變量的按鈕 - 它會成功打印一個包含40個元素的數組。 有人可以解釋爲什麼它是這樣工作嗎?

我期待這個變量應該在viewdidload方法中填充數據。

回答

1

您正在開始一個異步調用viewDidLoad,該調用在完成時設置爲self.importedRates = jsonresult

completionHandler一切print(importedRates)後具有非常高的概率執行,更精確地說:當時,網絡請求回來(這取決於你的網絡和要求,在幾微秒到幾分鐘上)

這就是按鈕按下的原因:當你按下按鈕時,請求完成並正確地填充數組。

非常不鼓勵在主線程上使用同步請求。這可能會導致您的應用程序無響應(因爲所有用戶輸入都在主線程中處理,並且只要同步呼叫正在等待響應就不能繼續進行)。

相反,如果您期望的數據到達,請調用方法從使用中你希望它被使用的方式,現在設置的屬性completionHandler內的視圖控制器舉例來說,如果你試圖填充self.tableView : UITableView!

let task = session.dataTaskWithURL(url!, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in 

      if error != nil { 
       self.successfullyConnected = false 
      }else { 
       var jsonresult = NSArray() 
       do { 
        jsonresult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSArray 
         dispatch_async(dispatch_get_main_queue()) { 
         self.importedRates = jsonresult 
         self.tableView.reloadData() // look here 
} 
       } catch _ { 
        print("error loading rates") 
       } 
      } 
     }) 

     task.resume() 
+0

這是有道理的,謝謝。有沒有辦法創建非異步調用?:)讓所有的命令一個接一個地執行 – Almazini

+0

@Almazini,我更新了我的答案。 – SmokeDispenser

+0

@SmokeDispanser你只添加了一行還是有更多的改變?對我而言,由於某種原因它不起作用。有沒有辦法處理CompletionHandler? – Almazini

相關問題