I currentl have a class B which inhertis from the AVCapturePhotoCaptureDelegate protocol, which is set on B’s initiazation, however, when i try to use this delegate inside class A, the protocol methods ends up not being called. E.g it looks something like this:
class A {
private var photoOutput = AVCapturePhotoOutput()
@objc func captureFrame() {
...
let b = B(a: self)
photoOutput.capturePhoto(with: photoSettings, delegate: b)
}
func somemethod() {
...
}
}
class B: AVCapturePhotoCaptureDelegate {
weak var a: A?
weak var delegate: AVCapturePhotoCaptureDelegate?
init(a: A) {
self.a = a
super.init()
self.delegate = self
}
// photoOutput does not end up getting called...
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
print("Delegate method called")
a.somemethod()
}
}
The reason that i want to do it like this is that the captureFrame method might end up being called in an iteration and we want to persist some data passed in as agurments to avoid race conditions.
It’s quite possible that i’ve misunderstood how this should work.
I have also tried calling the delegate variable direcrly, e.g:
photoOutput.capturePhoto(with: photoSettings, delegate: b.delegate)
2
Answers
Since you make it
week
hereYou need to retain it inside class
A
so replaceWith
Edit:
When you make the code like this
everything will be deallocated at the end of the function execution , so
b
will be released and when this happens the 2 variables inside itWill also be released with the main object , leaving your delegate listener a
nil
so your methodphotoOutput
won’t be called as the containing object is deallocated , but when you makeb
as instance variable it will exist as the containing object A exists , so the method will be called eventually.You need to consider how you want to manage the lifetime of
B
here. At the end ofcaptureFrame
, there’s no reference tob
anymore, so it is released. You likely want to manage it as a property ofA
, maybe along these lines:This would allow all calls to
captureFrame
to share a single B (which could be correct). Alternately, you could hold them in a Dictionary or Array if you need to manage separate instances of B for each call.If you want calls to
captureFrame
to cancel previous in-progress calls, then @Shehata’s approach is a way to do that (though I would use a regular Optional there rather than!
). Every timeb
is set, it releases the previous object.Based on your comments below about managing multiple calls, and dealing with a payload, I believe this is the approach you’re looking for: