变量在完成处理程序之外变为 nil [重复]

Posted

技术标签:

【中文标题】变量在完成处理程序之外变为 nil [重复]【英文标题】:Variable becomes nil outside completion handler [duplicate] 【发布时间】:2019-04-16 19:19:23 【问题描述】:

我不确定这是否重复,我搜索并找不到答案。如果是,请指出类似的问题。 我正在完成处理程序中设置 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 异步工作。将 print 行——以及你需要做的所有其他事情——放入完成处理程序中 完成处理程序异步返回。当你调用requestContentEditingInput时,机器不会等待返回再继续,它会继续执行代码。而且,很明显,在机器执行下一行之前,完成处理程序还没有返回。 我一个小时前刚刚回答了同样的问题。 ***.com/questions/55712286/…请阅读programmingios.net/…及相关文章 谢谢大家。 @matt 我知道这一定令人沮丧,但有时您在遇到问题时不知道要搜索的正确关键字。可能,如果我搜索“异步”之类的内容,我会找到您所指的答案,但我不知道我必须搜索它。也感谢您的文章。 【参考方案1】:

很遗憾,您无法以您想要的方式“修复”它。理论上,这里的完成处理程序可能会被同步调用(即,在调用requestContentEditingInput 时),但可以(并且很可能会)在资产准备好后的某个时间调用。这可能包括实际的downloading 或在其他线程上发生的任何其他不可预测的耗时资产准备。

换句话说,函数requestContentEditingInput 立即返回给您(并且您的代码继续执行),但该函数也开始在后台执行一些工作。该后台工作完成后,会调用您的处理程序块。

执行流程的性质意味着您根本无法保证(当然也不能假设)处理程序将在执行移至您的print(imageURL) 行之前被调用。

不过,这种异步性是一种非常常见的模式!没什么好害怕的。您需要将必须随后运行的任何代码放在该处理程序块中(或者如果在您的文件中更清晰,则从处理程序块调用另一个函数)。

【讨论】:

【参考方案2】:

很可能直到稍后才调用完成,因为代码在另一个线程上运行。尝试在完成块内放置一个打印语句,以查看代码执行的顺序。

【讨论】:

【参考方案3】:

当您使用处理程序时,每次构建使用线程的时间可能不同。

我建议您创建一个将在处理程序内部调用的方法。

像这样:

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)


【讨论】:

以上是关于变量在完成处理程序之外变为 nil [重复]的主要内容,如果未能解决你的问题,请参考以下文章

从 swift 评估 javascript 函数,在完成处理程序中得到 nil

如何制作一个 nil 兼容的完成处理程序?

添加完成处理程序以防止结果“nil”

请求完成处理程序致命错误:在展开可选值异常时意外发现 nil

Alamofire 请求最初返回值,但在通过完成处理程序时被接收为 nil

Swift-使用完成处理程序更新闭包外的全局变量