gpt4 book ai didi

swift - 如何利用 NSLock 来防止函数触发两次?

转载 作者:搜寻专家 更新时间:2023-10-31 08:10:28 30 4
gpt4 key购买 nike

我目前有一组异步函数,它们都在 viewDidLoad() 中调用。每个函数的末尾都有一个 bool 值,在函数完成时将其从 false 设置为 true。还有一个条件语句检查触发第三个函数的两个函数的 bool 值。这个条件语句在两个函数中都有(我想在两个函数都完成时调用)。一般:

var checkOne = false
var checkTwo = false

func functionOne(){
//async stuff
checkOne = true
if checkOne == true && checkTwo == true{
functionThree()//will only run if both functionOne and functionTwo have been completed
}
}

func functionTwo(){
//async stuff
checkTwo = true
if checkOne == true && checkTwo == true{
functionThree()//will only run if both functionOne and functionTwo have been completed
}
}

func functionThree(){
//stuff
}


override func viewDidLoad() {

functionOne()
functionTwo()
}

此设置确保 functionThree() 只能在 functionOnefunctionTwo 完成时运行。如果 functionOnefunctionTwo() 之前完成它的异步操作并达到触发 functionThree() 的条件,它不会像 >checkTwo 尚未变为真。因此,当 functionTwo() 的异步内容完成时,它将触发 functionThree() 。这可以正常工作,并且一次都没有引起问题。不过,我想明确避免的是异步函数碰巧要完成,因此在准确的同时调用functionThree()。为此,我想设置一个 NSLock(),但是,尽管查阅了文档,但我对如何执行此操作一无所知,因为我需要由两个不同的函数处理同一个锁。有人有什么想法吗?

最佳答案

NSLockmutex ;它防止多个线程同时访问同一个资源,这正是您在这里想要做的。一旦一个线程获得锁,其他试图获得锁的线程将等待,直到第一个线程释放锁。

您需要创建一个锁并将其存储在函数调用之间和函数调用之间持续存在的某个位置,在本例中很可能是在一个实例变量中。要获取锁,请调用它的 lock 方法,要释放它,请使用 unlock:

var checkOne = false
var checkTwo = false

//create the lock
let lock = NSLock()

func functionOne(){
//async stuff
//acquire the lock
lock.lock()
checkOne = true
if checkOne == true && checkTwo == true{
functionThree()//will only run if both functionOne and functionTwo have been completed
}
//release the lock
lock.unlock()
}

func functionTwo(){
//async stuff
lock.lock()
checkTwo = true
if checkOne == true && checkTwo == true{
functionThree()//will only run if both functionOne and functionTwo have been completed
}
lock.unlock()
}

func functionThree(){
//stuff
}


override func viewDidLoad() {

functionOne()
functionTwo()
}

一种更“现代”的方法是使用 DispatchQueue而不是 NSLock。 Dispatch 比 NSLock 和 NSThread 等 API 更高级;您将使用队列而不是直接使用锁和线程。

串行调度队列的工作方式类似于商店的结账线。您将代码块提交到队列,它会按照收到的顺序一次一个地执行它们。您还可以通过将 .concurrent 传递给 DispatchQueue 初始化程序的 options 参数来创建同时执行其任务的并发调度队列。

串行调度队列是一种保护资源不被多个线程同时访问的简单方法——只需为该资源创建一个队列,并将对该资源的每次访问都放在队列中。

var checkOne = false
var checkTwo = false

//Create a serial dispatch queue
let queue = DispatchQueue(label: "name of queue")

func functionOne(){
//async stuff

//Add a task to the queue, and execute it synchronously (i.e. wait for it to finish.)
//You can also use async to execute a task asynchronously,
//but sync is slightly more efficient unless you need it to be asynchronous.
queue.sync {
checkOne = true
if checkOne == true && checkTwo == true{
functionThree()//will only run if both functionOne and functionTwo have been completed
}
}
}

func functionTwo(){
//async stuff
queue.sync {
checkTwo = true
if checkOne == true && checkTwo == true{
functionThree()//will only run if both functionOne and functionTwo have been completed
}
}
}

func functionThree(){
//stuff
}


override func viewDidLoad() {

functionOne()
functionTwo()
}

关于swift - 如何利用 NSLock 来防止函数触发两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45202663/

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