I have stumbled across the following piece of code and I can't understand exactly how it works.
There is the following property which is populated when a method of AVCapturePhotoCaptureDelegate is called:
var photoCaptureCompletionBlock: ((UIImage?, Error?) -> Void)?
The delegate method is triggered by the following piece of code:
func captureImage(completion: @escaping (UIImage?, Error?) -> Void) {
let settings = AVCapturePhotoSettings()
self.photoOutput?.capturePhoto(with: settings, delegate: self)
self.photoCaptureCompletionBlock = completion
}
The line that triggers the delegate is:
self.photoOutput?.capturePhoto(with: settings, delegate: self)
and immediately after that the completion variable is assigned to self.photoCaptureCompletionBlock
Conceptually I would understand the opposite, i.e. to assign self.photoCaptureCompletionBlock to completion and not the other way around (which is not possible without an inout variable since completion is a let).
What are the mechanics behind this assignment? How does it work?
EDIT: For context, the delegate method that is called is the following:
func photoOutput(_ output: AVCapturePhotoOutput,
didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?,
previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?,
resolvedSettings: AVCaptureResolvedPhotoSettings,
bracketSettings: AVCaptureBracketedStillImageSettings?,
error: Error?) {
if let error = error {
self.photoCaptureCompletionBlock?(nil, error)
} else if let buffer = photoSampleBuffer,
let data = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: buffer, previewPhotoSampleBuffer: nil) {
let image = UIImage(data: data)
self.photoCaptureCompletionBlock?(image, nil)
} else {
self.photoCaptureCompletionBlock?(nil, CameraControllerError.unknown)
}
}