我正在使用应用程序从用户Camera Roll上传照片。作为上传的一部分,我需要计算照片的MD5(在上传之前检查重复项)。目前,由于malloc错误,应用程序经常崩溃。
为了追踪问题,我创建了一个简单的测试程序,它只生成设备上所有照片的MD5,并且该程序以相同的方式崩溃。
我使用的代码如下:
class ViewController: UIViewController {
@IBOutlet weak var numberOfPhotos: UILabel!
let imageManager = PHImageManager.default()
lazy var imageRequestOptions : PHImageRequestOptions = {
var options = PHImageRequestOptions()
options.isSynchronous = false
options.deliveryMode = .highQualityFormat
return options
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let collection = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumUserLibrary, options: nil).firstObject
let options = PHFetchOptions()
options.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.image.rawValue)
let allImages = PHAsset.fetchAssets(in: collection!, options: options)
allImages.enumerateObjects({
asset, index, stop in
self.imageManager.requestImageData(for: asset , options: self.imageRequestOptions, resultHandler: {
imageData,dataUTI,orientation,info in
if imageData != nil {
let digestLength = Int(CC_MD5_DIGEST_LENGTH)
var md5Buffer = [UInt8](repeating: 0, count: digestLength)
let _ = imageData!.withUnsafeBytes { (body: UnsafePointer<UInt8>) in
CC_MD5(body, CC_LONG(imageData!.count), &md5Buffer)
}
}
})
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
此程序将在失败前处理大约50张照片,并出现以下错误:
2016-10-14 15:51:41.565468 PhotoLoadTest[3513:804150] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** NSAllocateMemoryPages(7679134) failed'
*** First throw call stack:
(0x1910101c0 0x18fa4855c 0x191010108 0x191a6265c 0x191a38ac8 0x191a03404 0x100720fa8 0x1006c31f8 0x100015a38 0x19c77e930 0x10098525c 0x10098521c 0x10098a284 0x190fbdf2c 0x190fbbb18 0x190eea048 0x19296d198 0x196ec3818 0x196ebe550 0x100017ca8 0x18fecc5b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
通过Instruments运行程序时,我发现在程序崩溃之前,持久性内存使用率攀升至1.6 GB。
如果我注释掉CC_MD5
的电话,该程序运行正常......
我不会立即看到此程序泄漏内存的位置。你知道为什么会崩溃吗?
答案 0 :(得分:0)
autoreleasepool{
allImages.enumerateObjects({
asset, index, stop in
self.imageManager.requestImageData(for: asset , options: self.imageRequestOptions, resultHandler: {
imageData,dataUTI,orientation,info in
if imageData != nil {
let digestLength = Int(CC_MD5_DIGEST_LENGTH)
var md5Buffer = [UInt8](repeating: 0, count: digestLength)
let _ = imageData!.withUnsafeBytes { (body: UnsafePointer<UInt8>) in
CC_MD5(body, CC_LONG(imageData!.count), &md5Buffer)
}
}
})
})
}
上面的代码可能会工作,因为您正在遍历所有图像自动释放池将负责内存管理。