我尝试使用PHAsset从用户的相机胶卷中检索超过1,000张图像,但如果它只是缩略图,则会导致崩溃或花费很长时间。这是我的功能,我检索图像......
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 :(得分:1)
通常,您 希望加载大量的全尺寸或屏幕尺寸的图像并自行保存在内存中。对于那个尺寸,你一次只能呈现一个(或两个或三个,如果你想预先加载屏幕转换动画),所以你不需要获取超过一次。
同样,加载数百或数千个缩略图并自行缓存它们会导致内存问题。 (将您的集合视图反复告诉reloadData
会导致大量的流失。)相反,让Photos框架管理它们 - 它具有确保仅在需要时生成缩略图并在使用之间缓存的功能,甚至可以帮助您完成任务,例如在用户在集合视图中滚动时只抓取您需要的缩略图。
Apple的Using Photos Framework示例代码项目显示了几种获取图像的最佳做法。以下是一些主要观点的摘要:
AssetGridViewController
管理缩略图的集合视图,缓存初始化时给予它的PHFetchResult<PHAsset>
。有关获取结果的信息(如计数)是集合视图基本管理所需的全部内容。
AssetGridViewController
仅在集合视图要求显示单元格时,单独请求来自PHImageManager
的缩略图图像。这意味着我们只知道要看到一个单元格时才创建UIImage
,并且我们不必告诉集合视图一遍又一遍地重新加载所有内容。
就其本身而言,第2步将导致慢滚动,或者更确切地说,在滚动后减慢加载到单元格中的图像的追赶。所以,我们也这样做:
我们不使用PHImageManager.default()
,而是保留PHCachingImageManager
的实例,并告诉它我们想要的图像集是什么?预热&#34;用户滚动时的缓存。
AssetGridViewController
有一些额外的逻辑用于跟踪滚动视图的可见矩形,以便图像管理器知道为当前可见的项目准备缩略图(加上一点滚动向前),并且可以如果需要,项目的免费资源将不再可见。请注意,预取不会创建UIImage
,只需从磁盘启动必要的加载或从iCloud下载,因此您的内存使用率会保持很小。
在集合视图中选择项目时(要转到该照片的全屏演示文稿),AssetViewController
使用默认PHImageManager
请求屏幕大小(不完整) - 大小)图像。
机会投放意味着我们会立即获得质量较低的版本(基本上与我们之前在集合视图中使用的照片相同的缩略图),以及不久之后的更高质量版本(异步,之后我们自动更新视图。
如果您需要支持缩放(示例代码应用程序不支持,但它可能是真正的应用程序),您可以在完成后立即请求全尺寸图像 - 屏幕视图(以花费较长时间从放大缩略图转换为全屏图像为代价),或者通过请求屏幕大小的图像开始,然后还请求完整尺寸的图像以供以后传送。
< / LI> 醇>答案 1 :(得分:0)
在CellForRowAtIndexPath中使用PHImageManager的RequestImageForAsset方法来延迟加载UIImageView上的image属性。