2015-10-14 88 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