parsinggetDataInBackgroundWithBlock不按顺序获取

我从我的Parse类获取string,NSDate和PFFile填充集合视图单元格

所有的单元格正确加载图像,date,信息。 信息和date按正确顺序排列(按升序排列)。 但是,当我build立一些图像时不时会在不同的单元格。 我真的很抓我的头。 我猜这是与我怎么打电话mixPhoto.getDataInBackgroundWithBlock({

我曾尝试使用dispatch_async(dispatch_get_main_queue())

仍然没有运气…这里我的代码,任何人有任何想法?

@IBOutlet weak var collectionView1: UICollectionView! var mixPhotoArray : Array<UIImage> = [] var mixInfoArray: Array <String> = [] var mixDateArray: Array <NSDate> = [] override func viewDidLoad() { super.viewDidLoad() collectionView1.delegate = self; collectionView1.dataSource = self; self.queryParseMethod() self.getImageData() // Uncomment the following line to preserve selection between presentations // self.clearsSelectionOnViewWillAppear = false // Do any additional setup after loading the view. } func getImageData() { var query = PFQuery(className: "musicMixes") query.orderByAscending("date") query.findObjectsInBackgroundWithBlock { (objects: [AnyObject]!, error: NSError!) -> Void in for object in objects { let mixPhoto = object["mixPhoto"] as PFFile mixPhoto.getDataInBackgroundWithBlock({ (imageData: NSData!, error: NSError!) -> Void in if (error == nil) { dispatch_async(dispatch_get_main_queue()) { let image = UIImage(data:imageData) //image object implementation self.mixPhotoArray.append(image!) println(self.mixPhotoArray[0]) self.collectionView1.reloadData() } } else { println("error!!") } })//getDataInBackgroundWithBlock - end } }//for - end } func queryParseMethod() { var query = PFQuery(className: "musicMixes") query.orderByAscending("date") query.findObjectsInBackgroundWithBlock { (objects: [AnyObject]!, error: NSError!) -> Void in if error == nil { for object in objects { let mixPhoto = object["mixPhoto"] as PFFile let mixInfo = object["info"] as String let dateForText = object["date"] as NSDate //self.collectionView1.reloadData() self.mixDateArray.append(dateForText) self.mixInfoArray.append(mixInfo) self.collectionView1.reloadData() }//for - end } } } // end of queryParseMethod override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } */ // MARK: UICollectionViewDataSource func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { //#warning Incomplete method implementation -- Return the number of sections return 1 } func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { //#warning Incomplete method implementation -- Return the number of items in the section println("I have \(mixPhotoArray.count) Images") return mixInfoArray.count } //func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell:StreamCollectionViewCell = collectionView1.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as StreamCollectionViewCell cell.mixImage.image = mixPhotoArray[indexPath.item] cell.infoLabel.text = mixInfoArray[indexPath.item] // NSDate array into cell var dateFormatter = NSDateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd" cell.mixDateLabel.text = dateFormatter.stringFromDate(mixDateArray[indexPath.item]) return cell } 

就像Wain说的那样,我认为主要的问题是,因为你的图像是以不同的速度下载的,所以它们不一定会被依次追加到你的数组中。 虽然不build议你使用字典,但是我仍然build议在使用数组的同时避免这个问题:

 // Declare your mixPhotoArray such that it can store optionals var mixPhotoArray : Array<UIImage?> = [] func getImageData() { var query = PFQuery(className: "musicMixes") query.orderByAscending("date") query.findObjectsInBackgroundWithBlock { (objects: [AnyObject]!, error: NSError!) -> Void in // Initialize your array to contain all nil objects as // placeholders for your images self.mixPhotoArray = [UIImage?](count: objects.count, repeatedValue: nil) for i in 0...objects.count - 1 { let object: AnyObject = objects[i] let mixPhoto = object["mixPhoto"] as PFFile mixPhoto.getDataInBackgroundWithBlock({ (imageData: NSData!, error: NSError!) -> Void in if (error == nil) { dispatch_async(dispatch_get_main_queue()) { let image = UIImage(data:imageData) // Replace the image with its nil placeholder // and do so using the loop's current index self.mixPhotoArray[i] = image println(self.mixPhotoArray[i]) self.collectionView1.reloadData() } } else { println("error!!") } }) } } } 

然后在collectionView:cellForItemAtIndexPath ,您可以有条件地设置图像,使其只有在准备就绪后才会出现:

 if mixPhotoArray[indexPath.item] != nil { cell.mixImage.image = mixPhotoArray[indexPath.item] } 

您正在将数据存储在2个数组mixPhotoArraymixInfoArray ,但不能保证它们的顺序相同。 图像是不同的大小,所以他们将以不同的速度下载。 你也不应该试图一次下载超过4个,所以你目前的scheme不是很好。

相反,您应该有一个字典或自定义类的数组,其中包含所有的细节,并且当下载每个图像时,都会使用该图像进行更新。

显然这意味着你需要知道哪一个与你刚才下载的图像相关联,所以你需要在这个块中捕获这个字典/实例,以便更新它。

你可以像2个数组一样,只要你捕获一个索引,图像应该是在正确的位置插入图像到数组。