ios - 在串行队列中串行下载图像非常慢

标签 ios json swift grand-central-dispatch

要求 - 我有一个要求,即我收到一个 JSON 字典,从中检索图像和内容文本的数组。然后我必须在 Collection View 中显示所有具有相应内容的图像。

更新 - 最重要的是,我需要根据缩放到恒定宽度的图像大小来计算单元格大小(可能不正确)我需要完全下载所有图像然后重新加载 Collection View

问题 - 但问题是,当我在后台线程中下载图像并填充到单独的数组中时。然后图像无法按照 JSON 字典中的顺序添加,因为我正在将它们下载到并发队列中。

我的解决方案 - 所以我想到通过将所有内容放入串行队列来下载它们,这使得我检索数据非常慢。 什么是有效的替代方案?

代码-

let serialQueue = dispatch_queue_create("my serial queue", nil)

            dispatch_async(serialQueue, {

                print("This is first Method")

                for var i=0;i<self.resultArr.count;i++//resultArr is my array of data's in the jsonDic
             {



                    sleep(2)

                    print(self.resultArr[i].valueForKey("profile_pic")! as! String)
                    if self.resultArr[i].valueForKey("profile_pic")! as! String != "Null" && self.resultArr[i].valueForKey("profile_pic")! as! String != "null" && self.resultArr[i].valueForKey("profile_pic")! as! String != "NULL" && self.resultArr[i].valueForKey("profile_pic")! as! String != ""
                    {
                        let imageUrl = UrlClass.imageUrlWithoutExtension + String(self.resultArr[i].valueForKey("profile_pic")!)
                        print(imageUrl)
                        let url = NSURL(string: imageUrl)
                        let imageData = NSData(contentsOfURL: url!)

                        self.contentlabelArr.insertObject(String(self.resultArr[i].valueForKey("content")!), atIndex: i)

                        if imageData != nil && imageData?.length > 0
                        {
                            print("this is \(i) image")
                            print(UIImage(data: imageData!))

                            self.imageArr.insertObject(UIImage(data: imageData!)!, atIndex: i)
                        }
                        else
                        {
                            print("\(i) image has nill")
                            self.imageArr.insertObject(UIImage(named: "logo.png")!, atIndex: i)
                        }

                    }
                    else
                    {
                        print("\(i) image has nill")
                        self.contentlabelArr.insertObject(String(self.resultArr[i].valueForKey("content")!), atIndex: i)
                        self.imageArr.insertObject(UIImage(named: "logo.png")!, atIndex: i)
                    }

                    print("\(i) times 5 is \(i * 5)")

                    if self.imageArr.count==self.resultArr.count
                    {
                         print(self.resultArr.count)
                         print(self.imageArr.count)
                        dispatch_async(dispatch_get_main_queue(),
                            {
                                print(self.resultArr.count)
                                print(self.imageArr.count)
                                print(self.imageArr)
                                print(self.contentlabelArr)
                                self.collectionView?.reloadData()
                        })
                    }

最佳答案

更有效的方法是创建一个数据模型对象,它将代表您的图像链接和可选的 UIImage。像这样的事情:

class NetworkImage {
    let imageURL: String!
    let image: UIImage?
}

现在,当您收到带有图像链接数组的 JSON 时,您可以创建数据模型数组,该数组将遵循以下顺序:

let dataModel: [NetworkImage]

因此,当您异步检索图像时,您可以使用图像更新 dataModel,因此不会影响顺序。 这个想法可以根据您的需求进行演变。 您永远不应该对此类作业使用同步操作。

关于ios - 在串行队列中串行下载图像非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36908183/

相关文章:

swift - 你如何在 swift 中覆盖 layerClass

ios - 从 Firebase 下载 pdf 并将其本地存储在 iOS 上

ios - 如何显示树节点的当前位置

ios - 如何根据条件语句转至 View Controller ?

ios - UIPopoverPresentationController 未显示在正确的位置

ios - UIKeyboardWillHideNotification 上无法识别的选择器

javascript - 重新加载 angularJS 后在 Controller 和持久之间发送数据

python - PostgreSQL JSON - 嵌套列表的子集

python, json.loads 期望属性名称 : line 1 column 2 (char 2)

android - 用于 iOS 和 android 的具有键值存储和用户身份验证的云解决方案