我在主线程中发布了一条通知,我希望在收到该通知后在后台执行某些操作。
所以我将此方法与背景OperationQueue
一起使用
func addObserver(forName name: NSNotification.Name?,
object obj: Any?,
queue: OperationQueue?,
using block: @escaping (Notification) -> Void) -> NSObjectProtocol
我认为这应该可以,但是不能。
我已经读过有关doc的内容,但我对队列不了解,它说:
queue
The operation queue to which block should be added.
If you pass nil, the block is run synchronously on the posting thread.
因此,如果我们通过nil,该块将在发布线程上同步运行,但是如果我们通过queue
,它仍会同步运行在发布线程上?
我已经写了一些代码来测试我的想法,
import Foundation
let queue = OperationQueue()
let testNotification = Notification.Name("testNotification")
NotificationCenter.default.addObserver(forName: testNotification, object: nil, queue: queue) { _ in
print("receive notification: before sleep.")
Thread.sleep(forTimeInterval: 2)
print("receive notification: after sleep.")
}
NotificationCenter.default.post(name: testNotification, object: nil)
print("main thread")
RunLoop.main.run()
输出为:
receive notification: before sleep.
receive notification: after sleep.
main thread
因此该阻止确实在发布线程上同步运行。
我的问题是,此方法的意义是什么,参数queue
的意义是什么,我们什么时候应该使用它?
答案 0 :(得分:0)
我添加了:
import Foundation
let queue = OperationQueue()
let testNotification = Notification.Name("testNotification")
NotificationCenter.default.addObserver(forName: testNotification, object: nil,
queue: queue) { _ in
if queue == OperationQueue.current { print("I am in my queue") }
print("receive notification: before sleep.")
Thread.sleep(forTimeInterval: 2)
print("receive notification: after sleep.")
}
NotificationCenter.default.post(name: testNotification, object: nil)
print("main thread")
打印输出:
I am in my queue
receive notification: before sleep.
receive notification: after sleep.
main thread
我们可以知道它正在运行OperationQueue using
中的queue
块。
我的理解是,无论NotificationCenter.post
块在哪个队列中运行,using
方法都会一直等到using
块完成(同步)为止。有一个NotificationQueue缓冲区类可提供您正在寻找的功能。
NotificationCenter.default.addObserver(forName: testNotification, object: nil,
queue: queue) { _ in
print("receive notification: before sleep.")
Thread.sleep(forTimeInterval: 2)
print("receive notification: after sleep.")
}
NotificationQueue.default.enqueue(Notification(name: testNotification),
postingStyle: .whenIdle)
print("main thread")
打印出:
main thread
receive notification: before sleep.
receive notification: after sleep.
我认为使用queue
参数的原因是,如果使用串行队列进行访问控制,则可以传递queue
来使用。例如,UIKit使用main
队列来序列化所有屏幕操作。您可以执行类似的操作
NotificationCenter.default.addObserver(forName: testNotification, object: nil,
queue: OperationQueue.main) { _ in
// Do a bunch of UI stuff
}
因此,当您从后台队列更新模型时,可以向控制器发布通知以更新视图,并确保UIKit操作在main
队列中完成。