gpt4 book ai didi

ios - 如何确保在同一个后台线程上运行一些代码?

转载 作者:搜寻专家 更新时间:2023-10-30 21:52:37 29 4
gpt4 key购买 nike

我在我的 iOS Swift 项目中使用 Realm 。搜索涉及大数据集的复杂过滤器。所以我在后台线程上获取记录。

但是 realm 只能在创建 Realm 的同一个线程中使用。我正在保存在后台线程上搜索 Realm 后获得的结果引用。该对象只能从同一个后台线程访问

如何确保在不同时间将代码分派(dispatch)到同一个线程?

我按照下面的建议尝试解决了这个问题,但没有成功

let realmQueue = DispatchQueue(label: "realm")
var orginalThread:Thread?

override func viewDidLoad() {
super.viewDidLoad()

realmQueue.async {
self.orginalThread = Thread.current
}

let deadlineTime = DispatchTime.now() + .seconds(2)
DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
self.realmQueue.async {
print("realm queue after some time")

if self.orginalThread == Thread.current {
print("same thread")
}else {
print("other thread")
}
}
}
}

输出是

realm queue after some time

other thread

最佳答案

这是一个小型工作类,它可以在串行队列上以类似于异步调度的方式工作,并保证线程对所有工作项保持相同。

// Performs submitted work items on a dedicated thread
class Worker {

// the worker thread
private var thread: Thread?

// used to put the worker thread in the sleep mode, so in won't consume
// CPU while the queue is empty
private let semaphore = DispatchSemaphore(value: 0)

// using a lock to avoid race conditions if the worker and the enqueuer threads
// try to update the queue at the same time
private let lock = NSRecursiveLock()

// and finally, the glorious queue, where all submitted blocks end up, and from
// where the worker thread consumes them
private var queue = [() -> Void]()

// enqueues the given block; the worker thread will execute it as soon as possible
public func enqueue(_ block: @escaping () -> Void) {
// add the block to the queue, in a thread safe manner
locked { queue.append(block) }

// signal the semaphore, this will wake up the sleeping beauty
semaphore.signal()

// if this is the first time we enqueue a block, detach the thread
// this makes the class lazy - it doesn't dispatch a new thread until the first
// work item arrives
if thread == nil {
thread = Thread(block: work)
thread?.start()
}
}

// the method that gets passed to the thread
private func work() {
// just an infinite sequence of sleeps while the queue is empty
// and block executions if the queue has items
while true {
// let's sleep until we get signalled that items are available
semaphore.wait()

// extract the first block in a thread safe manner, execute it
// if we get here we know for sure that the queue has at least one element
// as the semaphore gets signalled only when an item arrives
let block = locked { queue.removeFirst() }
block()
}
}

// synchronously executes the given block in a thread-safe manner
// returns the same value as the block
private func locked<T>(do block: () -> T) -> T {
lock.lock(); defer { lock.unlock() }
return block()
}
}

只需实例化它并让它完成工作:

let worker = Worker()
worker.enqueue { print("On background thread, yay") }

关于ios - 如何确保在同一个后台线程上运行一些代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49043257/

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