gpt4 book ai didi

swift 。如何获取函数外变量的值

转载 作者:行者123 更新时间:2023-11-30 11:04:45 25 4
gpt4 key购买 nike

我正在研究机器人项目,并尝试将跟踪对象的位置作为 yTrack 变量的值(请参阅代码)。我可以从 func handleVisionRequestUpdate 打印 yTrack,但我需要访问此函数之外的 yTrack 以便将其与其他函数一起使用。以 getCoord() 为例。请帮忙!

import AVFoundation
import Vision
import UIKit
import Foundation

class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {

var protocolString: String?
var inputStream: InputStream?
var outputStream: OutputStream?
var dataAsString: String?
var yTrack: Double?

@IBOutlet private weak var cameraView: UIView?
@IBOutlet private weak var highlightView: UIView? {
didSet {
self.highlightView?.layer.borderColor = UIColor.red.cgColor
self.highlightView?.layer.borderWidth = 4
self.highlightView?.backgroundColor = .clear
}
}

private let visionSequenceHandler = VNSequenceRequestHandler()
private lazy var cameraLayer: AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession)
private lazy var captureSession: AVCaptureSession = {
let session = AVCaptureSession()
session.sessionPreset = AVCaptureSession.Preset.photo
guard
let backCamera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back),
let input = try? AVCaptureDeviceInput(device: backCamera)
else { return session }
session.addInput(input)
return session
}()

override func viewDidLoad() {
super.viewDidLoad()

self.highlightView?.frame = .zero
self.cameraView?.layer.addSublayer(self.cameraLayer)
let videoOutput = AVCaptureVideoDataOutput()
videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "MyQueue"))
self.captureSession.addOutput(videoOutput)
self.captureSession.startRunning()
}

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.cameraLayer.frame = self.cameraView?.bounds ?? .zero
}

public var lastObservation: VNDetectedObjectObservation?

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
guard
let pixelBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer),
let lastObservation = self.lastObservation
else { return }

let request = VNTrackObjectRequest(detectedObjectObservation: lastObservation, completionHandler: self.handleVisionRequestUpdate)
request.trackingLevel = .fast
do {
try self.visionSequenceHandler.perform([request], on: pixelBuffer)

} catch {
print("Throws: \(error)")
}
}

public func handleVisionRequestUpdate(_ request: VNRequest, error: Error?) {
test {(yTrack) in
DispatchQueue.main.async {
guard let newObservation = request.results?.first as? VNDetectedObjectObservation else { return }
self.lastObservation = newObservation
guard newObservation.confidence >= 0.3 else {
self.highlightView?.frame = .zero
return
}

self.transformedRect = newObservation.boundingBox
self.transformedRect!.origin.y = 1 - self.transformedRect!.origin.y
let convertedRect = self.cameraLayer.layerRectConverted(fromMetadataOutputRect: self.transformedRect!)
self.highlightView?.frame = convertedRect
}
}

let yTrack = Double(self.transformedRect?.origin.y ?? 0.5)
// HERE IT WORKS, yTrack IS PRINTING, BUT I NEED IT OUTSIDE THIS FUNCTION
print(yTrack as Any)
}

public func test (returnCompletion: @escaping (AnyObject) -> () ){
DispatchQueue.global(qos: .background).async {
self.yTrack = Double(self.transformedRect?.origin.y ?? 0.5)
returnCompletion(self.yTrack as AnyObject)
}
}

public func getCoord () {
//HERE IT DOESN'T WORK. NOTHING IS PRINTING FROM HERE.
print(yTrack)
}

最佳答案

问题出在您的 handleVisionRequestUpdate 函数上。

首先,@Azat 在评论中是正确的:当您声明 let yTrack = Double(self.transformedRect?.origin.y ?? 0.5) 时,您在此函数的范围内创建了新变量,其中与 ViewController 范围内的 var yTrack 没有任何联系。

因此,当您在此函数中打印 yTrack 时,您会打印函数的内部变量,该变量将在函数返回后被销毁。为了能够在函数外部使用 yTrack,您需要为 ViewControlleryouTrack 分配新值,然后您就可以在您想要的任何功能中使用它

yTrack = Double(self.transformedRect?.origin.y ?? 0.5)

第二个问题与DispatchQueue.main.async有关。大多数情况下,该 block 内的代码将在该 block 之后执行

let yTrack = Double(self.transformedRect?.origin.y ?? 0.5)
print(yTrack as Any)

那是因为使用这个 block 你告诉编译器“为这个代码块创建单独的“队列”,并在你能够做到的时候异步执行它”所以这一行self.transformedRect = newObservation.boundingBox 在大多数情况下都会在这行之后完成 let yTrack = Double(self.transformedRect?.origin.y ?? 0.5) 并且您将拥有之前的 transformedRect如果我理解正确的话,这一行里面的内容是nil。因此,请从此函数中删除 DispatchQueue.main.async 或将 self.yTrack = Double(self.transformedRect?.origin.y ?? 0.5) 移入其中。

关于 swift 。如何获取函数外变量的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52847883/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com