- Функция configureSession не может быть построена при доступе к captureManager.videoOutput в актер CaptureSession. Я мог бы это исправить, сделав функцию configureSession асинхронной и обернув весь код в закрытие задачи. Но затем, по мере расширения кода, мне нужно будет предпринять шаги для предотвращения повторного входа. Это единственный способ поговорить между двумя актерами или есть лучший выход?
- Все еще существует предупреждение. Отправка 'sampleBuffer' рискует вызывая гонки данных. Изолированный от задачи «sampleBuffer» захватывается изолированным от актера замыканием. изолированное от актера использование в замыкании может конкурировать с более поздними неизолированными использованиями в методе обратного вызова делегата. Нужно ли принудительно заключить его в структуру @Unchecked Sendable или есть более безопасный способ?
@preconcurrency import AVFoundation
actor CaptureManager: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate {
let captureQueue = DispatchSerialQueue(label: "Output Queue")
let videoOutput = AVCaptureVideoDataOutput()
// Sets the session queue as the actor's executor.
nonisolated var unownedExecutor: UnownedSerialExecutor {
captureQueue.asUnownedSerialExecutor()
}
override init() {
super.init()
// Set the delegate to receive video frames from camera
videoOutput.setSampleBufferDelegate(self, queue: captureQueue)
}
//Delegate method for receiving video frames
nonisolated func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
self.assumeIsolated { manager in
if let videoDataOutput = output as? AVCaptureVideoDataOutput {
manager.processVideoSampleBuffer(sampleBuffer, fromOutput: videoDataOutput)
}
}
}
func processVideoSampleBuffer(_ sampleBuffer:CMSampleBuffer, fromOutput: AVCaptureVideoDataOutput) {
//Do the processing
}
}
actor CaptureSession {
private let session = AVCaptureSession()
private let captureManager = CaptureManager()
init() {
Task {
await configureSession()
}
}
func configureSession() {
let videoOutput = captureManager.videoOutput //Build fails here
session.addOutput(videoOutput)
}
}
Подробнее здесь: https://stackoverflow.com/questions/793 ... munication