在串行队列中串行下载图像非常慢 [英] Downloading images serially in a serial queue very slow

查看:108
本文介绍了在串行队列中串行下载图像非常慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要求 -我有一个要求,即我要接收JSON字典,并从该字典中检索图像和内容文本的数组.然后,我必须在集合视图中显示具有相应内容的所有图像.

Requirement - I have a requirement in which I am receiving a JSON dictionary from which I am retrieving an array of images and content text. Then I have to display all the images with corresponding contents in a collection view.

更新- 首先,我需要根据图像大小计算出像元大小,该图像大小被缩放为一个固定的宽度(我可能不正确)需要完全下载所有图像,然后重新加载收藏夹视图

Update - Above all I need to calculate the cell size based on image size scaled to the a constant width for which I fell that(may not be correct) I need all images to be downloaded completely then reload collection view

问题-但是问题是,当我在后台线程中下载图像并填充到单独的数组中时,该图像的添加顺序与JSON词典中的顺序不同.正在并发队列中下载它们.

Problem - But the problem is that when I download the images in background thread and populate in separate arrays.Then the image cannot be added in the same order as they were in the JSON Dictionary since I am downloading them in a concurrent queue.

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

My Solution - So I thought of downloading them by putting everything in a serial queue which has made my retrieving data very slow. What can be an efficient alternative for this?

代码-

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()
                        })
                    }

推荐答案

如果使用并发队列,您肯定可以保留顺序.我认为您的代码几乎完全无法正确使用队列(为什么会有sleep(2)?),您的并发队列应位于forloop内,以便它可以同时触发不同的块,并且它们将使用分配给他们的for循环的正确索引将生成的图像放置在正确的数组位置

you definitely can keep the order if you use a concurrent queue. i think your code as it stands pretty much doesnt use the queue correctly at all (and why is there a sleep(2)?) your concurrent queue should be inside the forloop so it can fire off the different blocks at the same time, and they will use the correct index of the for loop that was assigned to them to place the resulting image in the correct array location

let sema = dispatch_semaphore_create(2); //depending how many downloads you want to go at once
for i in 0..<self.resultArr.count {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {

        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

        //download images here, order of execution will not be guaranteed, but after they are finished, they will always put the images in the array at 'i' so it doesnt matter

        dispatch_semaphore_signal(sema);
    })
}

这篇关于在串行队列中串行下载图像非常慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆