我面临的问题是人们说在collectionView中加载照片库时应用程序崩溃。大多数时候,他们有超过2-3数千张照片。对我来说,它工作正常。(我的图库中只有不到 1000 张照片(。
问题:也许有什么方法可以在集合中显示图像查看更"智能"并使用更少的内存?
附言也许当用户将所有照片都放在iCloud中时,也可能导致崩溃?因为直到现在,我认为该应用程序在将其加载到单元格中时不会下载照片。也许有人可以证明或不赞成这一事实。
这是我的函数:
func grabPhotos(){
let imgManager = PHImageManager.default()
let requestOptions = PHImageRequestOptions()
requestOptions.isSynchronous = false
requestOptions.deliveryMode = .opportunistic // Quality of images
requestOptions.isNetworkAccessAllowed = true
requestOptions.isSynchronous = true
requestOptions.progressHandler = { (progress, error, stop, info) in
print("progress: (progress)")
}
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
if let fetchResult : PHFetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions) {
if fetchResult.count > 0 {
for i in 0..<fetchResult.count {
imgManager.requestImage(for: fetchResult.object(at: i) , targetSize: CGSize(width: 150, height: 150), contentMode: .aspectFill, options: requestOptions, resultHandler: { image, error in
self.imageArray.append(image!)
self.kolekcija.reloadData()
})
}
}
else {
print("You got no photos")
kolekcija.reloadData()
}
}
}
问题是这一行:
self.imageArray.append(image!)
切勿制作图像数组。图像很大,你会用完内存。
这是一个集合视图。您只需按需提供图像itemForRowAt:
,您提供的是图像的小型版本(所谓的缩略图(,对于显示尺寸来说尽可能小。因此,任何时候都只有足够的缩略图来填充可见屏幕;这不会占用太多内存,而且当图像滚动到屏幕上时,运行时可以释放图像内存。
这就是PHCachingImageManager的用途。仔细看看 Apple 在他们的示例代码中如何处理这个问题:
https://developer.apple.com/library/archive/samplecode/UsingPhotosFramework/Listings/Shared_AssetGridViewController_swift.html
该示例中的任何地方都没有图像数组。
在 Swift 5 中工作。获取照片资源,但在 cellForItem 迭代之前不要加载照片。快乐编码。
var personalImages: PHFetchResult<AnyObject>!
func getPersonalPhotos() {
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
self.personalImages = (PHAsset.fetchAssets(with: .image, options: fetchOptions) as AnyObject?) as! PHFetchResult<AnyObject>?
photoLibraryCollectionView.reloadData()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return personalImages.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "insertCellIdentifierHere", for: indexPath) as! InsertACollectionViewCellHere
let asset: PHAsset = self.personalImages[indexPath.item] as! PHAsset
let itemWidth = photoLibraryCollectionView.frame.size.width / 2
let itemSize = CGSize(width: itemWidth, height: itemWidth / 2) // adjust to your preferences
PHImageManager.default().requestImage(for: asset, targetSize: itemSize, contentMode: .aspectFill, options: nil, resultHandler: {(result, info)in
if result != nil {
cell.photoImageView.image = result
}
})
cell.layoutIfNeeded()
cell.updateConstraintsIfNeeded()
return cell
}