2015-10-14 119 views
0

我有一個方法,它爲我解析JSON,然後在關閉加載並將圖像保存到磁盤。這個方法在viewDidLoad中被調用。然後加載表。問題是,當表加載時,它只有一個單元格,因爲在加載表時dataTaskWithRequest沒有足夠的時間下載所有信息。所以它加載一個單元格,然後如果我按下一個鏈接到函數tableView.reloadData()然後出現其他單元格的按鈕。用dataTaskWithRequest填充uitableview

如何使tableView等待dataTaskWithRequest並僅在從Internet獲取完成時自我展示?

下面的方法,我在viewDidLoad中調用看起來像

var JSONStorage : [Article?]? 
var objects = [Article?]() 
var imgPath : String? 

var battlesArticlesListImgPath : String? 
var battleArticlesListHash : String? 
var battleArticlesListArray = [ArticlesList?]() 

@IBOutlet weak var tableView: UITableView! 

@IBAction func button(sender: AnyObject) { 

    print(battleArticlesListArray) 
    print(battleArticlesListHash) 
    dump(battleArticlesListArray) 
    self.tableView.reloadData() 

} 

override func viewDidLoad() { 
    super.viewDidLoad() 

    downloadBattlesArticlesList() 

func downloadBattlesArticlesList() { 

    let number = arc4random_uniform(1000) 
    let urlString = "http://78.27.190.58:3200/api/category_listing/0/0/?\(number)" 


    if let url = NSURL(string: urlString) { 
     if let data = try? NSData(contentsOfURL: url, options: []) { 
      var json = JSON(data: data) 

      self.battleArticlesListHash = json["content_version"].stringValue 

      let UserDefaults = NSUserDefaults.standardUserDefaults() 
      UserDefaults.setValue(self.battleArticlesListHash, forKey: "battleArticlesListHash") 

      print("preved") 

      for element in json["listing"].arrayValue { 

       let id = Int(element["id"].stringValue) 
       let title = element["title"].stringValue 
       let subtitle = element["subtitle"].stringValue 
       let img = element["image"].stringValue 

       let url = NSURL(string: img) 
       let urlRequest = NSURLRequest(URL: url!) 
       let task = NSURLSession.sharedSession().dataTaskWithRequest(urlRequest, completionHandler: { 

        (data, response, error) -> Void in 

        let image = UIImage(data: data!) 

        var documentsDirectory:String? 

        var paths:[AnyObject] = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true) 

        if paths.count > 0 { 

         documentsDirectory = paths[0] as? String 

         var savePath = documentsDirectory! + "/\(self.randomStringWithLength(5)).jpg" 

         self.battlesArticlesListImgPath = savePath 

         NSFileManager.defaultManager().createFileAtPath(savePath, contents: data, attributes: nil) 

         let obj:ArticlesList = ArticlesList(id: id!, title: title, subtitle: subtitle, image: self.battlesArticlesListImgPath!) 

         self.battleArticlesListArray.append(obj) 

        } 
       }) 

      task.resume() 

      } 

     } 
    } 

    print(battleArticlesListArray) 
} 

最終打印也執行時顯示空數組。

+0

看看我的答案http://stackoverflow.com/questions/31279369/capturing-closure-values-in- swift/31279784#31279784它可以幫助你 –

回答

0

在您的viewDidLoad,隱藏你的tableView:

tableView.hidden = true 

這裏

 if paths.count > 0 { 

          documentsDirectory = paths[0] as? String 

          var savePath = documentsDirectory! + "/\(self.randomStringWithLength(5)).jpg" 

          self.battlesArticlesListImgPath = savePath 

          NSFileManager.defaultManager().createFileAtPath(savePath, contents: data, attributes: nil) 

          let obj:ArticlesList = ArticlesList(id: id!, title: title, subtitle: subtitle, image: self.battlesArticlesListImgPath!) 

          self.battleArticlesListArray.append(obj) 

         } 
tableView.hidden = false 
tableView.reloadData() 

這是因爲你的任務被提上一個背景胎面後,只需撥打tableView.reloadData()。一旦它返回了一些值,並且所有的任務都完成了,只需刷新tableview即可。

打印空白值的原因是因爲在數據返回之前它已經被執行。

此外,它是不是一個壞主意,看看iOS上的下穿文檔:這裏 https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/Introduction/Introduction.html