标签: dispatch-queue

处理多个完成处理程序

我正在尝试为数组中的每个元素协调几个完成处理程序.

代码基本上是这样的:

var results = [String:Int]()

func requestData(for identifiers: [String])
{
    identifiers.forEach
    {   identifier in

        service.request(identifier, completion: { (result) in
            result[identifier] = result
        })
    }

    // Execute after all the completion handlers finish
    print(result)
}
Run Code Online (Sandbox Code Playgroud)

因此,Array中的每个元素都通过带有完成处理程序的服务发送,并且所有结果都存储在一个数组中.完成所有这些处理程序后,我希望执行一些代码.

我试图这样做 DispatchQueue

var results = [String:Int]()

func requestData(for identifiers: [String])
{
    let queue = DispatchQueue.init(label: "queue")

    identifiers.forEach
    {   identifier in

        service.request(identifier, completion: { (result) in
            queue.sync
            {
                result[identifier] = result
            }
        })
    }

    // Execute after all the completion handlers finish
    queue.sync
    {
        print(result) …
Run Code Online (Sandbox Code Playgroud)

concurrency completionhandler swift dispatch-queue

5
推荐指数
1
解决办法
2247
查看次数

停止在主线程上运行的DispatchQueue

我有这段代码:

    DispatchQueue.main.asyncAfter(deadline: .now() + (delay * Double(isDelayAccounted.hashValue)) + extraDelay) {
        self.isShootingOnHold = false
        self.shoot()
        self.shootingEngine = Timer.scheduledTimer(timeInterval: (Double(60)/Double(self.ratePerMinute)), target: self, selector: #selector(ShootingEnemy.shoot), userInfo: nil, repeats: true)   
    }
Run Code Online (Sandbox Code Playgroud)

现在,我希望能够阻止此线程执行.怎么能阻止它被执行?例如,3秒后,我决定我不想再执行,所以我想停止它.

grand-central-dispatch swift dispatch-queue

4
推荐指数
2
解决办法
5660
查看次数

串行调度队列将仅使用一个线程?

我发现串行队列将使用多个线程来运行异步代码。这是操场上的测试代码。

import Foundation  

let q = DispatchQueue(label: "test")  
q.async {  
    print("hi \(Thread.current)")  
}  
q.async {  
    print("hi \(Thread.current)")  
}  
q.async {  
    print("hi \(Thread.current)")  
}  
q.async {  
    print("hi \(Thread.current)")  
}  
q.async {  
    print("hi \(Thread.current)")  
}  
Run Code Online (Sandbox Code Playgroud)

当我重复执行playground时,有时会出现这样的输出。根据我的理解,串行队列应该只使用一个线程,但日志显示它使用了 2 个线程。我对此真的很困惑。什么是正确的行为?

hi <NSThread: 0x7fc26a467b90>{number = 2, name = (null)}  
hi <NSThread: 0x7fc26a467b90>{number = 2, name = (null)}  
hi <NSThread: 0x7fc26a467b90>{number = 2, name = (null)}  
hi <NSThread: 0x7fc26a467b90>{number = 2, name = (null)}  
hi <NSThread: 0x7fc26b1003e0>{number = 3, name = (null)} 
Run Code Online (Sandbox Code Playgroud)

macos multithreading ios swift dispatch-queue

4
推荐指数
1
解决办法
2211
查看次数

将滤镜应用于实时相机预览-Swift

我正在尝试遵循此处给出的答案:https : //stackoverflow.com/a/32381052/8422218创建一个使用背面摄像头并添加滤镜的应用,然后将其实时显示在屏幕上

这是我的代码:

//
//  ViewController.swift
//  CameraFilter
//

import UIKit
import AVFoundation

class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {

    var captureSession = AVCaptureSession()
    var backCamera: AVCaptureDevice?
    var frontCamera: AVCaptureDevice?
    var currentCamera: AVCaptureDevice?

    var photoOutput: AVCapturePhotoOutput?

    var cameraPreviewLayer: AVCaptureVideoPreviewLayer?

    @IBOutlet weak var filteredImage: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        setupCaptureSession()
        setupDevice()
        setupInputOutput()
        setupCorrectFramerate(currentCamera: currentCamera!) // will default to 30fps unless stated otherwise
        setupPreviewLayer()
        startRunningCaptureSession()
    }

    func setupCaptureSession() {
        // should support anything up to 1920x1080 res, incl. 240fps @ …
Run Code Online (Sandbox Code Playgroud)

camera core-image ios swift dispatch-queue

3
推荐指数
1
解决办法
5205
查看次数

从后台线程播放 AVAudioPlayer 实例有时会失败

我正在尝试使用 Swift 5 中的 AVAudioPlayer 实例从后台线程播放声音。大多数时候,它会成功。但有时音频播放器无法播放声音。

\n\n

看起来好像连续调用 play() 两次,或者调用prepareToPlay() 然后连续调用 play() 以某种方式解决了问题,但这对我来说似乎不是一个好的解决方案,因为我担心这仍然不能解决问题不保证一定能播放成功。

\n\n
func setUpAudio() {\n    AVAudioSession.sharedInstance().perform(NSSelectorFromString("setCategory:error:"), with: AVAudioSession.Category.playback)\n    try! AVAudioSession.sharedInstance().setActive(true)\n    NotificationCenter.default.addObserver(self, selector: #selector(handleInterruption), name: AVAudioSession.interruptionNotification, object: nil)\n}\n\nfunc startNewAudio() {\n    let destinationData = Destinations.getDestinations()\n    var audio = destinationData[currentStop]!["audio"] as! String\n    if inTransit {\n        audio = destinationData[Paths.tourOrder[currentIndex + 1]]!["transit_audio"] as! String\n    }\n    let sound = NSURL(fileURLWithPath: Bundle.main.path(forResource: audio, ofType: "mp3", inDirectory: "audio")!)\n    try! audioPlayer = AVAudioPlayer(contentsOf: sound as URL)\n    audioPlayer.delegate = self\n    currentTime = 0\n    setPlay()\n}\n\nfunc setPlay() {\n    paused = …
Run Code Online (Sandbox Code Playgroud)

avaudioplayer ios swift ios-multithreading dispatch-queue

3
推荐指数
1
解决办法
3960
查看次数

如何正确使用DispatchQueue.main.async?

我的应用程序中有一个循环,可能需要几秒钟的时间来处理。

我希望当循环在后台运行时屏幕立即关闭。

这可能吗?

我尝试过仅添加循环:


DispatchQueue.main.async {
                for _ in 1...self.numberOfTransactionsToAdd {
                    
                    let newTransaction = Transaction()
                    
                    var timeAdded = 1.months
                    newTransaction.transactionAmount = self.amountTextField.text!.toDouble()
                    newTransaction.transactionDescription = self.descriptionTextField.text
                    newTransaction.transactionDate = self.datePicked
                    newTransaction.transactionCategory = self.categoryPicked
                    newTransaction.repeatInterval = self.repeatInterval
                    newTransaction.transactionSubCategory = self.subcategoryPicked
                    newTransaction.subCategoryName = self.subcategoryPicked!.subCategoryName
                    
                  
                    try! self.realm.write {
                        self.realm.add(newTransaction)
                    }
                    
                    self.datePicked = self.datePicked + timeAdded
                }
            }
                
            }

Run Code Online (Sandbox Code Playgroud)

我尝试添加整个功能:

    @IBAction func doneButtonPressed(_ sender: UIButton) {
        
        self.dismiss(animated: true, completion: nil)

        DispatchQueue.main.async {

            self.saveTransaction()

        }
        
    }
Run Code Online (Sandbox Code Playgroud)

但在视图消失之前屏幕仍然挂起。

这是我第一次使用DispatchQueue。我读过苹果公司的相关文档,但内容非常模糊。

这是解决这个问题的正确方法吗?

有人可以帮助指导新手采取正确的方法吗?

asynchronous for-loop swift dispatch-queue

3
推荐指数
1
解决办法
6095
查看次数

DispatchQueue 是否在自己的线程中运行?

我试图了解DispatchQueues真正的工作原理,我想知道假设DispatchQueues有自己的管理线程是否安全?例如,让我们以串行队列为例。根据我的理解 - 由于它是串行的,因此新任务只能在当前任务结束后才能启动,因此“某人”必须将新任务从队列中出队并提交执行!因此,基本上看来队列必须离开自己的线程,该线程将分派存储在队列中的任务。这是正确的还是我误解了什么?

grand-central-dispatch swift dispatch-queue

3
推荐指数
1
解决办法
2045
查看次数

SwiftUI:如何仅在用户停止在 TextField 中输入时运行代码?

所以我试图制作一个搜索栏,它不会运行显示结果的代码,直到用户停止输入 2 秒(也就是当用户输入新字符时它应该重置某种计时器)。我尝试使用 .onChange() 和 AsyncAfter DispatchQueue 但它不起作用(我想我明白为什么当前的实现不起作用,但我不确定我是否以正确的方式解决了这个问题)......

struct SearchBarView: View {
    @State var text: String = ""
    @State var justUpdatedSuggestions: Bool = false
    var body: some View {
        ZStack {
            TextField("Search", text: self.$text).onChange(of: self.text, perform: { newText in
                appState.justUpdatedSuggestions = true
                DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: {
                    appState.justUpdatedSuggestions = false
                })
                if justUpdatedSuggestions == false {
                    //update suggestions
                }
            })
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

textfield swift dispatch-queue swiftui

3
推荐指数
2
解决办法
308
查看次数

避免在 DispatchQueue 中使用 self

我想知道如何消除self. DispatchQueue作为一个好的实践,我们应该self只在init()

func loadAllClasses() {
    DispatchQueue.global(qos: .background).async {
      self.classVM.fetchAllClasses(id: id, completion: { (classes, error) in
        DispatchQueue.main.async {
          if error != nil {
            self.showAlert(message: "try again", title: "Error")
          }
          if let classes = classes {
            self.classesList = classes
            self.classesCollectionView.reloadData()
          }
        }
      })
    }
  }
Run Code Online (Sandbox Code Playgroud)

swift dispatch-queue

3
推荐指数
2
解决办法
5787
查看次数

为什么两个不同的串行队列会在 swift 中造成死锁?

我有一个自定义串行队列,在该队列中同步调用主队列。这正在造成僵局。根据我的理解,两者都是独立的队列,因此它应该可以工作,并且两个(步骤 3 和步骤 5)同步块都应该执行。谁能解释为什么会产生僵局?下面是我的游乐场代码。

func serialQueueTest() {
    let customSerialQueue = DispatchQueue(label: "com.test.dipak")
    
    print("Step 1")
    customSerialQueue.async {
        print("Step 2")
       
        DispatchQueue.main.sync {
            print("Step 3: Inside main sync queue")
        }
    }
    
    print("Step 4")
    customSerialQueue.sync {
        print("Step 5: Inside Custom Serial Queue sync queue")
    }
}
Run Code Online (Sandbox Code Playgroud)

objective-c grand-central-dispatch swift dispatch-queue

3
推荐指数
1
解决办法
874
查看次数