2016-01-21 48 views
0

我试图从PHAsset的用户相机胶卷中检索超过1,000张图像,但如果它只是缩略图,它最终会崩溃或需要很长时间。这里是我的功能,我检索图像...使用PHAsset检索多个图像

func retrieveImages(thumbnail: Bool) { 

    /* Retrieve the items in order of modification date, ascending */ 
    let options = PHFetchOptions() 
    options.sortDescriptors = [NSSortDescriptor(key: "modificationDate", 
     ascending: false)] 

    /* Then get an object of type PHFetchResult that will contain 
    all our image assets */ 
    let assetResults = PHAsset.fetchAssetsWithMediaType(.Image, 
     options: options) 

    let imageManager = PHCachingImageManager() 

    assetResults.enumerateObjectsUsingBlock{(object: AnyObject!, 
     count: Int, 
     stop: UnsafeMutablePointer<ObjCBool>) in 


     if object is PHAsset{ 
      let asset = object as! PHAsset 
      print("Inside If object is PHAsset, This is number 1") 

      var imageSize: CGSize! 

      if thumbnail == true { 
       imageSize = CGSize(width: 100, height: 100) 

      } else { 
       imageSize = CGSize(width: self.cameraView.bounds.width, height: self.cameraView.bounds.height) 

      } 
      /* For faster performance, and maybe degraded image */ 
      let options = PHImageRequestOptions() 
      options.deliveryMode = .FastFormat 
      options.synchronous = true 

      imageManager.requestImageForAsset(asset, 
       targetSize: imageSize, 
       contentMode: .AspectFill, 
       options: options, 
       resultHandler: { (image, _: [NSObject : AnyObject]?) -> Void in 
        if thumbnail == true { 
         self.libraryImageThumbnails.append(image!) 
         self.collectionTable.reloadData() 
        } else { 
         self.libraryImages.append(image!) 
         self.collectionTable.reloadData() 

        } 
      }) 

      /* The image is now available to us */ 

      print("enum for image, This is number 2") 



      print("Inside If object is PHAsset, This is number 3") 
     } 
     print("Outside If object is PHAsset, This is number 4") 

    } 



} 

请告诉我,如果需要更多的信息。谢谢!

+0

是的,1000张图像可能会占用很多内存......这是什么问题? – jtbandes

+0

@jtbandes我如何检索这些1000像Instagram的图像呢? –

+0

延迟加载,每次加载内存中的30个图像,当用户滚动加载下一个设置时,删除前一个。 – Shubhank

回答

0

在CellForRowAtIndexPath中,使用PHImageManager的RequestImageForAsset方法在您的UIImageView上延迟加载图像属性。

0

一般你不要想要加载吨的全尺寸或屏幕大小的图像,并保持他们自己的记忆。对于这种尺寸,您一次只能呈现一个(或两个或三个,如果要预加载屏幕转换动画),因此您不需要一次获取超过一个。

同样,加载数百或数千个缩略图并自己缓存它们会导致内存问题。 (一次又一次地反复收集视图到reloadData也会导致大量流失。)相反,让Photos框架管理它们 - 它具有确保只在需要时生成缩略图并在使用之间进行缓存的功能,甚至可以帮助您执行任务,例如只抓取用户在集合视图中滚动时所需的缩略图。

Apple的Using Photos Framework示例代码项目显示了几个获取图像的最佳实践。下面是一些主要观点总结:

  1. AssetGridViewController,管理缩略图集合视图,将缓存在初始化时给了它一个PHFetchResult<PHAsset>。有关获取结果的信息(如其计数)是集合视图的基本管理所需的全部信息。

  2. AssetGridViewController分别请求来自PHImageManager的缩略图图像,仅当收集视图要求显示单元格时。这意味着当我们知道一个单元格将被看到时,我们只创建一个UIImage,并且我们不必告诉集合视图重新加载所有内容。

第2步本身就会导致滚动缓慢,或者更确切地说,在您滚动后减缓图像加载到单元格中的速度。所以,我们也做:

  • 而不是使用PHImageManager.default(),我们保持PHCachingImageManager一个实例,告诉它我们想要的图像集“预热”缓存的作为用户滚动。

    AssetGridViewController有一些额外的逻辑用于跟踪滚动视图的可见矩形,以便图像管理器知道为当前可见项目准备缩略图(加上一点滚动提前),并且可以释放资源给项目不再可见,如果需要的话。请注意,预取不会创建UIImage,只需从磁盘启动必要的加载或从iCloud下载,以便您的内存使用量保持较小。

  • 论集视图中选择的项目(以原因请看到照片的全屏呈现),AssetViewController使用默认PHImageManager请求屏幕尺寸(未全尺寸)图像。

    机会性投放意味着我们将立即获得质量较低的版本(基本上照片已经从之前在集合视图中的使用中为我们缓存的相同缩略图),以及不久之后的较高质量版本之后我们会自动更新视图)。

    如果您需要支持缩放(示例代码应用程序不支持,但很可能是真实应用程序),则可以在进入全屏视图后立即请求全尺寸图像(在花费较长的时间从吹起的缩略图转换为全屏图像)或者通过请求屏幕大小的图像开始,然后请求全尺寸的图像以供以后交付。