2015-09-26 84 views
2

我有一个相当详细的问题,我认为具有广泛的异步知识的人可以帮助我。将图像从Parse加载到UICollectionView cell没有滞后

我有一个与“图片”对象填充的collectionView。这些对象是从一个自定义类创建的,然后再次使用从Parse(从PFObject)获取的数据填充这些对象。

首先,查询解析

func queryParseForPictures() { 
    query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, err: NSError?) -> Void in 
     if err == nil { 
      print("Success!") 
      for object in objects! { 
       let picture = Picture(hashtag: "", views: 0, image: UIImage(named: "default")!) 
       picture.updatePictureWithParse(object) 
       self.pictures.insert(picture, atIndex: 0) 
      } 
      dispatch_async(dispatch_get_main_queue()) { [unowned self] in 
       self.filtered = self.pictures 
       self.sortByViews() 
       self.collectionView.reloadData() 
      } 
     } 
    } 
} 

现在,我也得到了PFFile的PFObject内,但看到那转成PFFile NSData的也是一个异步调用(同步会阻止整个事情..),我无法弄清楚如何正确加载它。函数“picture.updatePictureWithParse(PFObject)”更新除UIImage以外的所有其他值,因为其他值是基本字符串等。如果我也从此函数中的PFFile中获取NSData,“collectionView.reloadData()”会触发在图片加载之前关闭,最后我会看到一大堆没有图片的图片。除非我强制重装或之后。因此,我将PFFile存储在对象中,以供将来在updatePictureWithParse中使用。下面是图片类里面的超级简单功能:

func updateViewsInParse() { 
    let query = PFQuery(className: Constants.ParsePictureClassName) 
    query.getObjectInBackgroundWithId(parseObjectID) { (object: PFObject?, err: NSError?) -> Void in 
     if err == nil { 
      if let object = object as PFObject? { 
       object.incrementKey("views") 
       object.saveInBackground() 
      } 
     } else { 
      print(err?.description) 
     } 
    } 
} 

为了让图像在半体面我已经实现了cellForItemAtIndexPath内的图片加载,但是这是可怕的。前10个或者其他任何东西都可以,但是当我向下滚动视图时,它会滞后很多,因为它必须从Parse中获取下一个单元格。见我下面执行:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(Constants.PictureCellIdentifier, forIndexPath: indexPath) as! PictureCell 

    cell.picture = filtered[indexPath.item] 

    // see if image already loaded 
    if !cell.picture.loaded { 
     cell.loadImage() 
    } 
    cell.hashtagLabel.text = "#\(cell.picture.hashtag)" 
    cell.viewsLabel.text = "\(cell.picture.views) views" 
    cell.image.image = cell.picture.image 

    return cell 
} 

和实际取是在细胞内:

func loadImage() { 
    if let imageFile = picture.imageData as PFFile? { 
     image.alpha = 0 
     imageFile.getDataInBackgroundWithBlock { [unowned self] (imageData: NSData?, err: NSError?) -> Void in 
      if err == nil { 
       self.picture.loaded = true 
       if let imageData = imageData { 
        let image = UIImage(data: imageData) 
        self.picture.image = image 
        dispatch_async(dispatch_get_main_queue()) { 
         UIView.animateWithDuration(0.35) { 
          self.image.image = self.picture.image 
          self.image.alpha = 1 
          self.layoutIfNeeded() 
         } 
        } 
       } 
      } 
     } 
    } 
} 

我希望你明白我的问题的感觉。在单元出队内部获取图像非常粗糙。另外,如果这几个片段没有给出完整的图片,请参阅此项目的github链接: https://github.com/tedcurrent/Anonimg

谢谢大家!

/T

回答

1

可能有点晚了,但是当加载PFImageView的距离在UICollectionView我发现这个方法是更有效的数据库,但我不完全知道为什么。我希望它有帮助。在您的cellForItemAtIndexPath中使用,而不是您的cell.loadImage()函数。

if let value = filtered[indexPath.row]["imageColumn"] as? PFFile { 
    if value.isDataAvailable { 
     cell.cellImage.file = value  //assign the file to the imageView file property 
     cell.cellImage.loadInBackground() //loads and does the PFFile to PFImageView conversion for you 
    } 
}