首先很明显你有内存崩溃。根据应用程序扩展编程指南 https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionCreation.html:
运行应用程序扩展的内存限制明显低于对前台应用程序施加的内存限制。在这两个平台上,系统可能会主动终止扩展,因为用户希望返回到主机应用程序中的主要目标。
从错误中可以明显看出,您超过了 120 mb。但您可能想知道是什么占用了这么多内存。
根据优化图像
乔丹·摩根 编剧 https://www.swiftjectivec.com/optimizing-images/:
iOS 本质上是根据图像的尺寸来获取内存占用的,而实际文件大小与之关系不大。
因此,如果我们计算尺寸或 4032 x 3024 照片,它将是... 4 位颜色为 46mb,8 位颜色为 79mb。相当大,但还不到极限......
事情是 - 你有two您的图像的副本。一张是原始的,第二张是旋转的。
要解决此问题,您只需将旋转图像加载到内存中,而不加载原始图像。这可以通过以下方式完成图像I/O框架 https://developer.apple.com/documentation/imageio:
extension UIImage {
static func imageWithFixedOrientation(at url: URL) -> UIImage? {
guard let imageSource = CGImageSourceCreateWithURL(url as CFURL, nil) else { return nil }
guard let imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as? Dictionary<CFString, Any> else { return nil }
guard
let width = imageProperties[kCGImagePropertyPixelWidth] as? CGFloat,
let height = imageProperties[kCGImagePropertyPixelHeight] as? CGFloat
else { return nil }
let options: [NSString: Any] = [
kCGImageSourceThumbnailMaxPixelSize: max(width, height),
kCGImageSourceCreateThumbnailFromImageAlways: true,
kCGImageSourceCreateThumbnailWithTransform: true
]
guard let cgImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, options as CFDictionary) else { return nil }
return UIImage(cgImage: cgImage)
}
}
在示例应用程序中:
extension ViewController: UIImagePickerControllerDelegate & UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true)
guard let url = info[.imageURL] as? URL else { return }
let image = UIImage.imageWithFixedOrientation(at: url)
}
}
它将内存峰值从 180+mb 减少到仅 80mb。