我正在尝试为数组中的每个元素协调几个完成处理程序.
代码基本上是这样的:
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) 我有这段代码:
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秒后,我决定我不想再执行,所以我想停止它.
我发现串行队列将使用多个线程来运行异步代码。这是操场上的测试代码。
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) 我正在尝试遵循此处给出的答案: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) 我正在尝试使用 Swift 5 中的 AVAudioPlayer 实例从后台线程播放声音。大多数时候,它会成功。但有时音频播放器无法播放声音。
\n\n看起来好像连续调用 play() 两次,或者调用prepareToPlay() 然后连续调用 play() 以某种方式解决了问题,但这对我来说似乎不是一个好的解决方案,因为我担心这仍然不能解决问题不保证一定能播放成功。
\n\nfunc 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) 我的应用程序中有一个循环,可能需要几秒钟的时间来处理。
我希望当循环在后台运行时屏幕立即关闭。
这可能吗?
我尝试过仅添加循环:
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。我读过苹果公司的相关文档,但内容非常模糊。
这是解决这个问题的正确方法吗?
有人可以帮助指导新手采取正确的方法吗?
我试图了解DispatchQueues真正的工作原理,我想知道假设DispatchQueues有自己的管理线程是否安全?例如,让我们以串行队列为例。根据我的理解 - 由于它是串行的,因此新任务只能在当前任务结束后才能启动,因此“某人”必须将新任务从队列中出队并提交执行!因此,基本上看来队列必须离开自己的线程,该线程将分派存储在队列中的任务。这是正确的还是我误解了什么?
所以我试图制作一个搜索栏,它不会运行显示结果的代码,直到用户停止输入 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) 我想知道如何消除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) 我有一个自定义串行队列,在该队列中同步调用主队列。这正在造成僵局。根据我的理解,两者都是独立的队列,因此它应该可以工作,并且两个(步骤 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) dispatch-queue ×10
swift ×10
ios ×3
asynchronous ×1
camera ×1
concurrency ×1
core-image ×1
for-loop ×1
macos ×1
objective-c ×1
swiftui ×1
textfield ×1