解析 JSON 冻结 tableView SWIFT

Posted

技术标签:

【中文标题】解析 JSON 冻结 tableView SWIFT【英文标题】:Parsing JSON freezes tableView SWIFT 【发布时间】:2016-07-25 08:12:12 【问题描述】:

我当前的问题是当函数updateLabels 被调用时,我的tableView 冻结了。 我的目标是每 15 秒更新一次广播电台的歌曲名称和标题。我有一个 dict 数组,其中包含每 15 秒填充一次该 dict 数组的信息和函数。每个站都有一个单独的JSON 链接文件,我将它放入我的getData 函数参数中。我该怎么做才能让它变得更好并阻止 tableView 冻结?

主数组

var songNames = [
                (songArtist: "", songName: ""),
                (songArtist: "", songName: ""),
                .....
            ]

更新歌曲名称和名称

func updateLabels() 
    songNames.removeAll()   
    songNames.append((songArtist: getData("rd").artistName, songName: " - \(getData("record").songName)"))
    songNames.append((songArtist: getData("mix").artistName, songName: " - \(getData("mix").songName)"))
    tableView.reloadData()

从 JSON 链接获取数据

func getData(urlPart: String) ->(artistName: String, songName: String) 
    let mainURl = "http://...json"
    let url = NSURL(string: mainURl)
    let jsonData = NSData(contentsOfURL: url!) as NSData!
    let readableJSON = JSON(data: jsonData, options: NSJSONReadingOptions.MutableContainers, error:  nil)
    let songArtistName = readableJSON["ARTIST"]
    let songName = readableJSON["NAME"]                
    return (songArtistName.description, songName.description)

在我的viewDidLoad

override func viewDidLoad() 
    super.viewDidLoad()
    updateLabels()
    //**Timer to call the function every 15 sec**
    NSTimer.scheduledTimerWithTimeInterval(15, target: self, selector: #selector(self.updateLabels), userInfo: nil, repeats: true)

【问题讨论】:

如果您在主线程上下载数据,它当然会冻结。查看如何异步执行此操作。 我需要使用 Alamofire 吗? 这很方便,因为这是标准的做法,但在你的情况下,它看起来不像。只需看看 dispatch_async 函数是如何工作的,并将其包装在您的下载代码中。当您需要更新 UI 时,不要忘记跳到主队列! 使用 NSURLSession。一个例子:***.com/questions/31264172/… 【参考方案1】:

嗯,主要问题是因为您在主线程上获取JSON 数据,这就是 UI 冻结的原因。而不是在主线程上执行此操作,您应该在后台线程上调度此任务async

async 后台任务结束时,ios SDK 会将程序流切换到主线程,您必须在主线程中使用获取的JSON 数据更新您的 UI 组件。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^

   // Get JSON data here

   dispatch_async(dispatch_get_main_queue(), ^
       // Update UI here
   );
);

【讨论】:

【参考方案2】:

如果您不知道,请尝试使用线程/Grand Central Dispatch。喜欢就好。。

dispatch_async(dispatch_get_main_queue(), () -> Void in

//call your function here..

)

如果没有解决,请在下方评论。我会提供帮助。

【讨论】:

我将我的 NSTimer 放入 dispatch_async 中,应用程序保持冻结状态 不需要使用 NSTimer.. 而不是 NSTimer 尝试使用这个 'dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), () -> Void in // 耗时任务' dispatch_async(dispatch_get_main_queue() , () -> 无效在 ) 它会只运行一次吗? 是的,它会......首先执行主队列,然后在后台执行另一个 wil 但我需要它每 15 秒执行一次

以上是关于解析 JSON 冻结 tableView SWIFT的主要内容,如果未能解决你的问题,请参考以下文章

在 tableview 中解析字典的 JSON 数组

解析 json 并用 tableview 显示

Swift4 JSON解析

如何从本地 JSON 文件解析数据并保存在模型类中并在 tableview 中使用

数据不会从 JSON 解析加载到某些 Tableview 单元格上

Objective C TableView清除Json解析