修改行数组时,Swift 2数据不会重新加载数据

Posted

技术标签:

【中文标题】修改行数组时,Swift 2数据不会重新加载数据【英文标题】:Swift 2 data is not reloading data when the array of rows is modified 【发布时间】:2015-11-06 12:37:10 【问题描述】:

我刚刚开始完全掌握 ios 开发和 Xcode,我正在使用 Swift 2 学习它。我正在尝试从 URL 获取一些 JSON 数据,将其拆分为 swift Array,并将其显示在TableView 中。我已设法将 JSON 数据拆分为 Array,但我无法重新加载表的数据以使其显示。这是我的代码:

//
//  ViewController.swift
//  Table JSON
//
//  Created by James Allison on 06/11/2015.
//  Copyright © 2015 James Allison. All rights reserved.
//

import UIKit

class ViewController: UIViewController 

    var cellContent = ["this should be replaced","something","something else"]

    @IBOutlet weak var table: UITableView!
    override func viewDidLoad() 
        super.viewDidLoad()

        // construct url
        let url = NSURL(string: "http://127.0.0.1:8888/json.php")!

        let task = NSURLSession.sharedSession().dataTaskWithURL(url)  (data, response, error) -> Void in
            // the following will happen when the task is complete
            if let urlContent = data 

                var webContent =  NSString(data: urlContent, encoding: NSUTF8StringEncoding)

                // remove []
                webContent = webContent?.stringByReplacingOccurrencesOfString("[", withString: "")
                webContent = webContent?.stringByReplacingOccurrencesOfString("]", withString: "")

                // split by commas
                var webContentArr = webContent?.componentsSeparatedByString(",")

                var temp = ""
                // remove quote marks
                for var i = 0; i < webContentArr!.count; i++ 
                    temp = webContentArr![i]
                    temp = temp.stringByReplacingOccurrencesOfString("\"", withString: "")
                    webContentArr![i] = temp
                

                print(webContentArr!)
                self.cellContent = webContentArr! as! Array
                self.table.reloadData()

            
            else 
                // something failed
                print("Error: invalid URL or something.")
            
        
        task.resume()

    

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return cellContent.count
    

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
        let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
        cell.textLabel?.text = cellContent[indexPath.row]

        return cell
    

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



在我运行它的那一刻,表格显示原始的cellContent 变量,但不是新的变量。没有产生错误,并且数组打印正常。

编辑:感谢 Joshua 的回答。我最终使用以下代码来解决我的问题:

dispatch_async(dispatch_get_main_queue(),  () -> Void in
     self.cellContent = webContentArr! as! Array
     self.table.reloadData()
)

【问题讨论】:

【参考方案1】:

猜测,您的“任务完成时会发生”代码正在除 main 之外的某个线程/队列上运行,这与 UI 更新不兼容。任何接触 UI 必须在主队列上完成。

您应该调整您的代码,以便在处理完所有内容后,将替换cellContent 和对reloadData() 的表视图调用都安排在主队列中。为此,请将上述两个调用包装在发送到主队列的异步调度中:

dispatch_async(dispatch_get_main_queue(), ^

    self.cellContent = webContentArr! as! Array
    self.table.reloadData()

);

这将确保cellContent 数组在更新主队列上的 UI 时不会“在表格视图的后面”被修改(糟糕!),并且表格视图在完成之前不会再次尝试更新任何正在进行的更新。

我希望这会有所帮助。

【讨论】:

不客气。 :-) 这是一个非常重要的话题,尤其是在与任何 UI 对象交互时。每当您传递需要在运行时更新 UI 的闭包(稍后运行的代码块)时,请记住“跳回”到主队列以更新任何集合(例如您的 cellContent 数组)或其他UI 需要的属性,并更新 UI 本身。

以上是关于修改行数组时,Swift 2数据不会重新加载数据的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 在使用 Swift 中的 Master Detail App 滚动之前不会重新加载

iCloud 同步后 UITableView 不会重新加载(Swift 2)

关闭块不会在第二次 swift3 上重新加载表

Swift:在警报视图中按下按钮后,tableView 不会重新加载数据

Swift UITableView 重新加载数据

CollectionViewCell 中标签中的数据有时会在重新加载时刷新,有时则不会