我怎么会在初始化期间失败?

How can I fail during an init?

我正在尝试创建这个 class:

class CaptureVideoDataOutput: AVCaptureVideoDataOutput, AVCaptureVideoDataOutputSampleBufferDelegate {

  private let imageCaptureModel: ImageCaptureModel

  override init() {
    super.init()
  }
  
  convenience init?(imageCaptureModel:ImageCaptureModel) {
    self.imageCaptureModel = imageCaptureModel
    
    let queueID = "\(Bundle.main.bundleIdentifier!).captureDeviceOutput"
    let captureVideoDataOutputQueue = DispatchQueue(label: queueID,
                                                    attributes: DispatchQueue.Attributes.concurrent)
    
    let captureVideoDataOutput = CaptureVideoDataOutput()
    captureVideoDataOutput.videoSettings = videoSettingsParameter
    captureVideoDataOutput.setSampleBufferDelegate(captureVideoDataOutput, queue: captureVideoDataOutputQueue)
    
    guard
      imageCaptureModel.captureSession.canAddOutput(captureVideoDataOutput) else {
      return nil
    }
    self = captureVideoDataOutput
  }

这个想法是用户只使用方便的初始化,如果整个事情在守卫上失败,或者如果成功则接收对象。

但此代码在第一行失败

let' property 'imageCaptureModel' may not be initialized directly; use "self.init(...)" or "self = ..." instead

在最后一行加上

Cannot assign to value: 'self' is immutable

有什么想法吗?

CaptureVideoDataOutput 创建一个附加的(私有)初始化器,它接受 ImageCaptureModel 并在便利初始化器中调用它而不是 CaptureVideoDataOutput():

  private init(_ model: ImageCaptureModel) {
    self.imageCaptureModel = model
    super.init()
  }

  convenience init?(imageCaptureModel:ImageCaptureModel) {
    let queueID = "\(Bundle.main.bundleIdentifier!).captureDeviceOutput"
    let captureVideoDataOutputQueue = DispatchQueue(label: queueID,
                                                    attributes: DispatchQueue.Attributes.concurrent)

    self.init(imageCaptureModel)
    videoSettings = videoSettingsParameter
    setSampleBufferDelegate(captureVideoDataOutput, queue: captureVideoDataOutputQueue)

    guard
      imageCaptureModel.captureSession.canAddOutput(captureVideoDataOutput) else {
      return nil
    }
  }

请注意,非便利初始化器也可能 return nil,所以我不确定您为什么选择此设置。考虑一下:

init?(model: ImageCaptureModel) {
    self.imageCaptureModel = model
    let queueID = "\(Bundle.main.bundleIdentifier!).captureDeviceOutput"
    let captureVideoDataOutputQueue = DispatchQueue(label: queueID,
                                                    attributes: DispatchQueue.Attributes.concurrent)

    super.init()
    videoSettings = videoSettingsParameter
    setSampleBufferDelegate(captureVideoDataOutput, queue: captureVideoDataOutputQueue)

    guard
        imageCaptureModel.captureSession.canAddOutput(captureVideoDataOutput) else {
        return nil
    }
}