为什么应用程序被信号量阻塞?
Why app is blocked by semaphore?
我有以下功能,假设 return [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
}
但它卡在信号量等待中,没有继续前进。我浏览了很多教程,但 GCD 的其他变体不起作用。我认为这是因为模拟器,我不知道,无法在真实设备上测试。请帮忙
requestContentEditingInputWithOptions
内的守卫回调闭包阻止信号发送到信号量。
在这种情况下(当您需要清理操作时)最好使用 defer。你的情况:
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)
}
更新
除了清理错误之外,还有一个。在主线程上调用 requestContentEditingInputWithOptions
的完成关闭。这意味着如果你用信号量阻塞主线程:完成闭包也会阻塞执行。要修复阻塞的信号量问题,您需要在与主线程不同的线程上调用 getCIImages
。
无论如何,让异步的东西同步是错误的。你应该考虑不同的方法。
我有以下功能,假设 return [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
}
但它卡在信号量等待中,没有继续前进。我浏览了很多教程,但 GCD 的其他变体不起作用。我认为这是因为模拟器,我不知道,无法在真实设备上测试。请帮忙
requestContentEditingInputWithOptions
内的守卫回调闭包阻止信号发送到信号量。
在这种情况下(当您需要清理操作时)最好使用 defer。你的情况:
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)
}
更新
除了清理错误之外,还有一个。在主线程上调用 requestContentEditingInputWithOptions
的完成关闭。这意味着如果你用信号量阻塞主线程:完成闭包也会阻塞执行。要修复阻塞的信号量问题,您需要在与主线程不同的线程上调用 getCIImages
。
无论如何,让异步的东西同步是错误的。你应该考虑不同的方法。