当我尝试在UICollectionView中显示用户的照片库时,应用程序崩溃

时间:2016-06-09 09:13:59

标签: ios swift uicollectionview

我的ViewController看起来像:顶部的摄像头视图和底部的照片库,就像在Instagram中一样。

当我尝试加载用户的图像库并在UICollectionView上显示时,应用程序崩溃了Memory Warning。如何防止它并改善我的功能?

我的功能:

func getImagesFromLibrary(from: Int = 0, to: Int = 5, completion: (loaded: Bool) -> Void) {
    if images.count > 0 {
        for i in from..<to {
            let asset: PHAsset = self.images[i] as! PHAsset
            let imageFetchOptions = PHImageRequestOptions()

            self.imageManager.requestImageForAsset(asset, targetSize: CGSize(width: 75, height: 75), contentMode: .AspectFit, options: imageFetchOptions, resultHandler: { (image: UIImage?, info: [NSObject : AnyObject]?) in
                if (image != nil) {
                    if let img = image {
                        self.croppedImagesArray[i] = img
                        self.imagesCollectionView.reloadData()
                    }
                }
            })
        }

        completion(loaded: true)
    } else {
        print("Images Empty")
    }
}

我通过以下方式致电:

        if AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo) ==  AVAuthorizationStatus.Authorized {
        print("GRANTED")
        self.getImagesFromLibrary { (loaded) in
            if loaded {
                print("Images Count: \(self.images.count)")

                if self.images.count > 5 {
                    print("Second part")
                    self.getImagesFromLibrary(5, to: self.images.count / 2, completion: { (loaded) in
                        if loaded {
                            self.getImagesFromLibrary(self.images.count / 2, to: self.images.count, completion: { (loaded) in })
                        }
                    })
                }
            }
        }
    }

所以,现在我在我的画廊中有300张图片。这很重要,这就是我的应用程序在加载过程中崩溃的原因。

我该如何解决?任何解决方案?

2 个答案:

答案 0 :(得分:0)

显然,您只是在内存中保留了太多图像,因此会收到内存警告 当您收到内存警告时,iOS会让您有机会发布易于重新创建的数据。如果您不这样做,您的应用程序可以随时终止。

所以问题是你是否真的需要将所有这些图像保存在记忆中 如果是这样,您就会遇到真正的问题,iOS可能不适合您的应用平台 如果没有,例如如果您想一次只显示部分加载的图像,则应使用在应显示的图像不在内存中时显示的占位符图像,下载图像,并尽快用实际图像替换占位符它已被下载。

存储图片以便不会收到内存警告的一种方法是使用NSCache&lt; Docs&gt ;,这类似于NSMutableDictionary,其中您可以存储图像,但是当内存变紧时,将会自动清除未长时间使用的图像。因此,如果您必须显示图像,则可以先显示占位符,然后尝试从缓存中加载它,如果失败,则下载它。
当然,还有一些框架可以自动为您进行缓存,例如AFNetworking&lt; Github&gt;。

答案 1 :(得分:0)

默认情况下,requestImageForAsset:是异步的。您编写的代码将立即触发对所有300个图像的请求,并且您看到内存不足。所以加载5个图像的代码,然后是前半部分,然后是后半部分,只是一次运行。

我建议在UICollection cellForRowAtIndexPath中:你调用self.imageManager.requestImageForAsset(self.images [indexPath.item] ....并在结果处理程序块中为该单元格设置UImageView。无需预加载所有300张图像,用户可能永远不会滚动查看全部。而其他人可能有3000张或更多图像。

同样在结果处理程序中,每次获取图像时都调用collectionView reloadData,甚至在当前甚至不显示所获取的图像时重新加载。使用reloadItemsAtIndexPath:只加载与图像关联的单元格。