skip to Main Content

I have the following class:

class Scanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate {}

It has a delegate method implemented in the class from AVCaptureVideoDataOutputSampleBufferDelegate:

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection)
    {}

Even when I set the function to private, fileprivate, or internal, it still appears in the code-complete in Xcode:

enter image description here

Is there a way to hide this call from outside class use?

2

Answers


  1. One way is to create a private inner class that conforms to the protocol, and have the inner class hold a weak reference to the outer class, in case you need to use members from the outer class in the implementation of the delegate method.

    class Scanner {
        ...
    
        private class VideoOutputDelegate: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate {
            weak var scanner: Scanner?
            init(scanner: Scanner) { self.scanner = scanner }
    
            func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
                ...
            }
        }
    
        private let videoOutputDelegate = VideoOutputDelegate(scanner: self)
    }
    

    Rather than setting the sampleBufferDelegate to self, you can set it to videoOutputDelegate instead.

    (I think), AVCaptureVideoDataOutput holds a weak reference to its sampleBufferDelegate, so videoOutputDelegate here is the only strong reference here that is keeping the object alive.

    Login or Signup to reply.
  2. Your problem is somewhat related to the Single Responsibility Principle. Basically your class tries to do one more task than needed – reacting to AVFoundation events, in this case the captureOutput method.

    Recommending to split your class in two, have one class that handles all the AVFoundation setup/delegate, and have Scanner only deal with raw data. This way:

    • you keep the concerns separated, which allows you to reuse the Scanner in other contexts too
    • you might even be able to remove the AVFoundation dependency from the scanner, making it more independent
    • you don’t get the undesired functionality, as yes, a scanner doesn’t need to expose AVFoundation delegate methods.

    Also, most likely your scanner doesn’t need a AVCaptureConnection to do its work, but unfortunately this dependency is leaked into the class due to the delegate. And splitting the responsibilities helps with this problem too.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search