And*_* M. -1 semaphore grand-central-dispatch ios swift phasset
我有以下功能,假设[CIImage]为了我的目的返回- 在tableView中显示照片的一些元数据.
func getCIImages() -> [CIImage] {
var images = [CIImage]()
let assets = PHAsset.fetchAssetsWithMediaType(.Image, options: nil)
for i in 0..<assets.count {
guard let asset = assets[i] as? PHAsset else {fatalError("Cannot cast as PHAsset")}
let semaphore = dispatch_semaphore_create(0)
asset.requestContentEditingInputWithOptions(nil) { contentEditingInput, _ in
//Get full image
guard let url = contentEditingInput?.fullSizeImageURL else {return}
guard let inputImage = CIImage(contentsOfURL: url) else {return}
images.append(inputImage)
dispatch_semaphore_signal(semaphore)
}
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
}
return images
}
Run Code Online (Sandbox Code Playgroud)
但它停留在信号量等待,并没有走得更远.我已经浏览了很多教程,但GCD的其他变种不起作用.我认为这是因为模拟器,我不知道,无法在真实设备上进行测试.请帮忙.
requestContentEditingInputWithOptions回调闭包内的警卫阻止信号发送到信号量.在这种情况下(当您需要清理操作时)最好使用延迟.在你的情况下:
asset.requestContentEditingInputWithOptions(nil) { contentEditingInput, _ in
defer { dispatch_semaphore_signal(semaphore) }
//Get full image
guard let url = contentEditingInput?.fullSizeImageURL else {return}
guard let inputImage = CIImage(contentsOfURL: url) else {return}
images.append(inputImage)
}
Run Code Online (Sandbox Code Playgroud)
UPDATE
除了清理bug之外还有另外一个.requestContentEditingInputWithOptions调用主线程完成关闭.这意味着如果使用信号量阻塞主线程:完成闭包也会被阻止执行.要修复阻塞的信号量问题,您需要getCIImages在与main不同的线程上调用.
无论如何使异步事物同步是错误的.你应该想到不同的方法.
| 归档时间: |
|
| 查看次数: |
367 次 |
| 最近记录: |