Приведенный ниже код моделирует две задачи камеры с использованием AVFoundation — настройку сеанса захвата и получение/обработку кадров с камеры. Обе функции реализованы как актеры и иногда могут взаимодействовать друг с другом. Swift 6 установлен в качестве версии языка Swift для компиляции. Здесь у меня мало сомнений:
Функция 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)
}
}
}
Приведенный ниже код моделирует две задачи камеры с использованием AVFoundation — настройку сеанса захвата и получение/обработку кадров с камеры. Обе функции реализованы как актеры и иногда могут взаимодействовать друг с другом. Swift 6 установлен в качестве версии языка Swift для компиляции. Здесь у меня мало сомнений: [list] [*]Функция 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) } } }