現在、ユーザーが選択したフォルダー内で提供されているすべての画像をダウンロードする作業を行っています。したがって、このプロセスは次のように構成されます。
- 画像のすべてのサムネイルをリクエストする
- すべてのオリジナル画像をリクエストする
- オリジナルを取得し、Retina 圧縮バージョンを作成して表示します
オリジナルを保持する必要がある理由は、それが 8x10 の額縁から 40x40 のキャンバス ラップまで印刷するファイルであるためです。そのため、オリジナルが重要です。クラッシュを引き起こしている唯一の部分は、オリジナルを取得して圧縮バージョンを作成することです。私はこれを使用することになりました:
autoreleasepool({
self.compressed = self.saveImageWithReturn(image:self.original!.scaledImage(newSize: 2048), type: .Compressed)
})
次を呼び出して画像をスケーリングします。
func scaledImage(newSize newHeight : CGFloat) -> UIImage {
let scale = newHeight / size.height
let newWidth = size.width * scale
UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight))
drawInRect(CGRectMake(0, 0, newWidth, newHeight))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
これを使用して、画像をデバイス ドキュメントに保存します。
private func saveImageWithReturn(image img: UIImage, type: PhotoType) -> UIImage? {
guard let path = ASSET_PATH.URLByAppendingPathComponent(type.rawValue).path,
let imageData = UIImageJPEGRepresentation(img, type.compression())
else { return nil }
imageData.writeToFile(path, atomically: true)
return UIImage(data: imageData)
}
クラッシュのautoreleasepool
問題は実際に修正されていますが、メインスレッドで動作しているため、基本的にすべてのユーザー操作がフリーズしています。それから私は試しました
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), {
autoreleasepool({
self.compressed = self.saveImageWithReturn(image: self.original!.scaledImage(newSize: 2048), type: .Compressed)
})
})
その結果、メモリが十分に迅速に解放されず、クラッシュします。これが起こっていると私が信じる理由はscaledImage(newSize: 2048)
、複数のリクエストがスタックするのに十分な速度で処理されておらず、すべてがこれを処理しようとし、複数のインスタンスがすべて元のイメージを保持しようとすると、メモリ警告またはクラッシュが発生するためです。これまでのところ、iPad Air 2 で完全に動作することはわかっていますが、iPad Generation 4 では処理が遅いようです。
これが最善の方法なのか、元のファイルをスケーリングおよび圧縮する別の方法を見つける必要があるのか はわかりません。どんな助けでも本当に感謝しています。