Return 同步调用闭包时闭包的值(PHImageManager with isSynchronous = true)

Return value from closure when closure is called synchronously (PHImageManager with isSynchronous = true)

我调用的api设计是异步的,但也有同步模式。我正在使用 PHImageManager.requestImageDataAndOrientation (docs) 来请求图像文件,同时编写更具可读性(线性)的代码。

let requestImageOptions = PHImageRequestOptions()
requestImageOptions.isSynchronous = true

var photos: [Data] = []

let requestIdentifier = PHImageManager.default().requestImageDataAndOrientation(for: asset, options: requestImageOptions) { [weak &photos] (imageData, dataUTI, orientation, info) in
    photos.append(imageData)
}

// do stuff with photos here because the previous call is synchronous

不幸的是,错误消息没有帮助:Expected name of in closure capture list。我对 &photos 的尝试是使用值类型变量的引用,因为不能直接引用值类型。有人能给我指出正确的方向吗?


这可能是 common question 对于那些错误地认为他们可以在方法调用下面立即获得价值的人来说,他们认为调用是同步的,但实际上不是。不过,就我而言,我已将调用配置为 同步 。我也知道我可以在闭包中完成所有工作,但是我将无法从带有数据的函数中 return 。当然,我可以尝试使用 class(值类型)将数据传出闭包。

编译器反对,因为闭包开头的 [weak &photos] 语法无效。

你不需要关心捕获局部变量的闭包photos;它不会导致保留循环。

不过您确实需要有条件地解包 imageData

同样重要的是要注意,如果您从后台队列调用 requestImageDataAndOrientation,则只能使用同步选项。您的代码没有显示后台队列调度。如果您确实在后台队列上执行调用,则需要将任何 UI 更新分派回主队列。

鉴于此,使用异步形式并在完成闭包中简单地执行您需要的处理可能更简单。

let requestIdentifier = PHImageManager.default().requestImageDataAndOrientation(for: asset, options: requestImageOptions) {(imageData, dataUTI, orientation, info) in
    guard let imageData = imageData else
    { return }
    photos.append(imageData)
}