- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我目前有一组异步函数,它们都在 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()
只能在 functionOne
和 functionTwo
完成时运行。如果 functionOne
在 functionTwo()
之前完成它的异步操作并达到触发 functionThree()
的条件,它不会像 >checkTwo
尚未变为真。因此,当 functionTwo()
的异步内容完成时,它将触发 functionThree()
。这可以正常工作,并且一次都没有引起问题。不过,我想明确避免的是异步函数碰巧要完成,因此在准确的同时调用functionThree()
。为此,我想设置一个 NSLock()
,但是,尽管查阅了文档,但我对如何执行此操作一无所知,因为我需要由两个不同的函数处理同一个锁。有人有什么想法吗?
最佳答案
安NSLock
是 mutex ;它防止多个线程同时访问同一个资源,这正是您在这里想要做的。一旦一个线程获得锁,其他试图获得锁的线程将等待,直到第一个线程释放锁。
您需要创建一个锁并将其存储在函数调用之间和函数调用之间持续存在的某个位置,在本例中很可能是在一个实例变量中。要获取锁,请调用它的 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/
我需要在发出异步请求之前设置一个互斥锁,然后在另一个线程上的这个请求的回调中解锁互斥锁。 苹果文档说: Warning: The NSLock class uses POSIX threads to
我有一个以 a 开头的循环 [lock lock]; 因为在循环体中我正在创建另一个线程,该线程需要在循环再次运行之前完成。 (完成后另一个线程将解锁它)。 但是在第二个循环中我收到以下错误: 201
我有一个属性@property NSLock *myLock 我想写两个方法: - (void) lock 和 - (void) unlock 这些方法分别锁定和解锁myLock并且无论调用它们的线程
我有一个全局变量,可以从多个线程访问,包括从主线程访问。我想使用 NSLock because it’s faster than GCD . 这是我正在尝试做的事情: struct Synchroni
使用 NSLock 在我们的日志中看到这条消息: *** -[NSLock lock]: deadlock ( '(null)') *** Break on _NSLockError() to deb
我正在审查一些 Alamofire sample重试代码: func should(_ manager: SessionManager, retry request: Request, with
我目前有一组异步函数,它们都在 viewDidLoad() 中调用。每个函数的末尾都有一个 bool 值,在函数完成时将其从 false 设置为 true。还有一个条件语句检查触发第三个函数的两个函数
我正在处理多线程代码。数据访问通过“NSLock”对象锁定在多个部分。我想确保在这些部分中调用的某些方法会检查是否获得了适当的锁。 类似于: assert([myLock isSet] == YES)
我应该做一个NSLock应用程序委托(delegate)中的实例,供所有类使用?还是建议让每个类实例化自己的NSLock根据需要实例? 例如,如果我可以访问分布在两个 View Controller
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 2 年前。 Improv
在这种情况下,我必须等待 UIKit 动画完成,并且我正在使用完成 block 来执行相关的最终代码。现在我已经意识到,当我从主线程调用该函数两次时,我可以触发一个引入错误的竞争条件。我无法使用简单的
我正在编写代码来渲染和旋转一张图片,其细节正在同时计算和更新。它在单个线程(带有显示链接)上无错误地工作,但看起来很笨重,而且我不希望显示链接触发计算。所以我想在主线程(带有显示链接)中执行所有与 O
我遇到了线程安全问题。我有一个队列,当我修改内容时导致跨线程错误。我以前没用过锁,但我想试试。我在为我的队列操作支持 NSMutableArray 的所有代码周围添加了一个锁。我认为,问题是我没有对所
我有一段代码经常被主线程或其他几个后台线程访问。我需要确保一次只处理一个代码。 我目前正在使用 @synchronized(self) { } block ,但我不确定它是否提供了正确的保护。它与 N
我一直在使用 NSLock 来同步敏感的代码部分,但一直遇到问题,因为它们必须从锁定它们的同一线程解锁。然后我发现 GCD 的 DispatchSemaphore 似乎在做同样的事情,而且更方便的是它
从编程的角度来看,由于代码的编写方式,我不一定能解决这个问题。 基本上,用伪代码表示: if NSUserDefaults' stored token exists{ setFlag(toke
谁能简要说明这 3 个系统在线程安全方面的优缺点? 通过观看最近的 WWDC 视频,我感觉到 Apple 正在插入 GCD 的使用,以创建线程安全的高性能读写器。 这背后的想法/支持是什么?是时候访问
我阅读了有关 GCD 队列的 Apple 文档,开始想知道如果我让修改类型为 NSMutableArray 的实例成员在串行队列中不是线程安全的,会发生什么情况?串行队列会保证我串行执行操作,但我仍然
我是 Objective-C 的新手。如果我有一个类属性可能会在 API 调用等异步事件期间被修改,那么确保在其他人访问属性时更改属性的最佳方法是什么线程不会导致崩溃? 据我所知,我有两个选择: 1)
我有一些 Objective-C 代码,它使用 NSLock 来实现某种事务。该对象在“开始事务”上被锁定,在锁定到位的情况下进行了几次其他调用,然后通过“提交”将其释放。我正在编写一个 JNI 粘合
我是一名优秀的程序员,十分优秀!