变量在完成处理程序之外变为 nil
Variable becomes nil outside completion handler
我不确定这是否重复,我搜索过但找不到答案。如果是,请指出类似的问题。
我在完成处理程序中设置 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。为什么会发生这种情况?如何解决它而不必在完成处理程序块中编写所有后续代码?
不幸的是,您不能 "fix" 以您喜欢的方式进行。此处的完成处理程序在理论上可能会被同步调用(即,在调用 requestContentEditingInput
时),但可以(而且很可能会)在资产准备好后的某个时间被调用。这可能包括实际的 downloading 或在其他线程上发生的任何其他不可预测的耗时资产准备。
换句话说,函数 requestContentEditingInput
returns 马上给你(你的代码继续执行),但函数也开始在后台做一些工作。该后台工作完成后会调用您的处理程序块。
执行流程的性质意味着您根本无法保证(当然也不能假设)处理程序会在执行进入您的 print(imageURL)
行之前被调用。
不过,这种异步性是一种非常常见的模式!没什么好怕的。您需要随后将 必须 运行 的任何代码放入该处理程序块中(或者从处理程序块调用另一个函数,如果该函数在您的文件中更清晰)。
很可能直到稍后才调用完成,因为代码在另一个线程上 运行。尝试在完成块中放置一条打印语句,以查看代码的执行顺序。
当您使用处理程序时,每个构建的线程时间可能不同。
我建议您创建一个将在处理程序内部调用的方法。
像这样:
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)
}
我不确定这是否重复,我搜索过但找不到答案。如果是,请指出类似的问题。 我在完成处理程序中设置 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。为什么会发生这种情况?如何解决它而不必在完成处理程序块中编写所有后续代码?
不幸的是,您不能 "fix" 以您喜欢的方式进行。此处的完成处理程序在理论上可能会被同步调用(即,在调用 requestContentEditingInput
时),但可以(而且很可能会)在资产准备好后的某个时间被调用。这可能包括实际的 downloading 或在其他线程上发生的任何其他不可预测的耗时资产准备。
换句话说,函数 requestContentEditingInput
returns 马上给你(你的代码继续执行),但函数也开始在后台做一些工作。该后台工作完成后会调用您的处理程序块。
执行流程的性质意味着您根本无法保证(当然也不能假设)处理程序会在执行进入您的 print(imageURL)
行之前被调用。
不过,这种异步性是一种非常常见的模式!没什么好怕的。您需要随后将 必须 运行 的任何代码放入该处理程序块中(或者从处理程序块调用另一个函数,如果该函数在您的文件中更清晰)。
很可能直到稍后才调用完成,因为代码在另一个线程上 运行。尝试在完成块中放置一条打印语句,以查看代码的执行顺序。
当您使用处理程序时,每个构建的线程时间可能不同。
我建议您创建一个将在处理程序内部调用的方法。
像这样:
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)
}