我不确定这是否是重复的,我搜索了一下,找不到答案。如果是,请指出我类似的问题。 我正在完成处理程序中设置 imageURL 变量的值:
var imageURL: URL?
let options = PHContentEditingInputRequestOptions()
imageAsset.requestContentEditingInput(with: options, completionHandler: { (contentEditingInput: PHContentEditingInput?, _) in
imageURL = contentEditingInput?.fullSizeImageURL
})
//prints nil
print(imageURL)
现在,处理程序中 imageURL 的值不是 nil,而是在 (在 print 语句中) 之后变为 nil。为什么会发生这种情况,我如何在不必将所有后续代码写入完成处理程序块的情况下修复它?
不幸的是,您无法以您想要的方式"修复"它。理论上,这里的完成处理程序可以同步调用(即,在调用requestContentEditingInput
时),但可以(并且很可能)在稍后资产准备就绪时的某个时间调用。这可能包括实际下载或发生在其他线程上的任何其他不可预测的耗时的资产准备。
换句话说,函数requestContentEditingInput
立即返回给您(并且您的代码继续执行),但该函数也开始在后台执行一些工作。该后台工作完成后,将调用您的处理程序块。
执行流的性质意味着您根本无法保证(当然也不能假设)在执行移动到print(imageURL)
行之前将调用处理程序。
不过,这种异步性是一种非常常见的模式!没什么好怕的。您需要将随后必须运行的任何代码放在该处理程序块中(或者如果文件中更干净,则从处理程序块调用另一个函数)。
很可能直到稍后才会调用完成,因为代码正在另一个线程上运行。尝试在完成块内放置一个 print 语句,以查看代码的执行顺序。
使用处理程序时,每次生成线程的时间可能会有所不同。
我建议您创建一个将在处理程序中调用的方法。
喜欢这个:
func edit(){
var imageURL: URL?
let options = PHContentEditingInputRequestOptions()
imageAsset.requestContentEditingInput(with: options, completionHandler: { (contentEditingInput: PHContentEditingInput?, _) in
imageURL = contentEditingInput?.fullSizeImageURL
display(url:imageURL)
})
}
func display(url: String) {
print(imageURL)
}