TableView上的Swift JSON数据滞后

时间:2015-12-01 21:09:10

标签: ios json swift uitableview

我的TableView显示JSON数据存在问题。当它显示时,无论何时我向上和向下滚动它都会滞后。我知道我必须使用Grand Central Dispatch方法(GCD),但是,我不知道如何去做。

这是我的viewDidLoad()方法中的代码片段,它只是将JSON数据抓取到字典中:

// Convert URL to NSURL
    let url = NSURL(string: apiURL)

    let jsonData: NSData?

    do {
        /*
        Try getting the JSON data from the URL and map it into virtual memory, if possible and safe.
        DataReadingMappedIfSafe indicates that the file should be mapped into virtual memory, if possible and safe.
        */
        jsonData = try NSData(contentsOfURL: url!, options: NSDataReadingOptions.DataReadingMappedIfSafe)
    } catch let error as NSError
    {
        showErrorMessage("Error in retrieving JSON data: \(error.localizedDescription)")
        return
    }

    if let jsonDataFromApiURL = jsonData
    {
        // The JSON data is successfully obtained from the API

        /*
        NSJSONSerialization class is used to convert JSON and Foundation objects (e.g., NSDictionary) into each other.
        NSJSONSerialization class's method JSONObjectWithData returns an NSDictionary object from the given JSON data.
        */

        do
        {
            let jsonDataDictionary = try NSJSONSerialization.JSONObjectWithData(jsonDataFromApiURL, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary

            // Typecast the returned NSDictionary as Dictionary<String, AnyObject>
            dictionaryOfRecipes = jsonDataDictionary as! Dictionary<String, AnyObject>

            // Grabs all of the matched recipes
            // This will return an array of all of the matched recipes
            matchedRecipes = dictionaryOfRecipes["matches"] as! Array<AnyObject>

            // Returns the first 10 recipes shown in the JSON data
            recipeCount = matchedRecipes.count

        }catch let error as NSError
        {
            showErrorMessage("Error in retrieving JSON data: \(error.localizedDescription)")
            return
        }
    }

    else
    {
        showErrorMessage("Error in retrieving JSON data!")
    }

谢谢!

2 个答案:

答案 0 :(得分:1)

将您的代码放在

dispatch_async(dispatch_get_main_queue(), {
// Your Execution Code
}

这只是工作

答案 1 :(得分:0)

我已经弄明白了。它不仅仅是

dispatch_async(dispatch_get_main_queue())

因为那只是使用主线程,所以只有在将JSON信息显示到视图上时才应该使用它。如果我理解正确,你应该使用:

 dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)){}

每次尝试下载数据(如图像),然后再将其显示到视图上。以下是任何感兴趣的人的示例代码:

    //-----------------
    // Set Recipe Image
    //-----------------
    dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0))
    {
        // This grabs the Image URL from JSON
        let imageURL = recipeDataDict["imageUrlsBySize"] as! NSDictionary
        let imageSize90 = imageURL["90"] as! String

        // Create an NSURL from the given URL
        let url = NSURL(string: imageSize90)

        var imageData: NSData?

        do {
            /*
            Try getting the thumbnail image data from the URL and map it into virtual memory, if possible and safe.
            DataReadingMappedIfSafe indicates that the file should be mapped into virtual memory, if possible and safe.
            */
            imageData = try NSData(contentsOfURL: url!, options: NSDataReadingOptions.DataReadingMappedIfSafe)
        } catch let error as NSError
        {
            self.showErrorMessage("Error in retrieving thumbnail image data: \(error.localizedDescription)")
        }
        dispatch_async(dispatch_get_main_queue(),
        {
            if let image = imageData
            {
                // Image was successfully gotten
                cell.recipeImage!.image = UIImage(data: image)
            }
            else
            {
                self.showErrorMessage("Error occurred while retrieving recipe image data!")
            }
        })
    }

在我没有main_queue线程的dispatch_get_global_queue之前,图像下载速度非常慢(但是tableview没有滞后)。但是,一旦我在显示JSON数据之前添加了main_queue,它就立即(或几乎立即)下载并且没有任何进一步的滞后。

有关以下内容的更多信息:https://tetontech.wordpress.com/2014/06/04/swift-ios-and-grand-central-dispatch/