我有一个基于NSDocument的Cocoa应用程序,向用户展示文本文档。文档内容是在后台队列中读取的,这导致了一个问题。
我使用 NSAttributedString
与图像,即它可以含有 NSTextAttachment
和 NSTextAttachmentCell
. 当我尝试初始化一个图片的附件,并且我在Xcode中激活了主线程检查器,我得到了以下错误。
// On background queue:
let attachment = NSTextAttachment()
attachment.attachmentCell = NSTextAttachmentCell(imageCell: image) <-
"[NSCell init] must be used from main thread only"
我的第一次尝试是将该代码包裹在 DispatchQueue.main.sync {}
但是,这造成了一个僵局,即 NSDocument
当自动保存或用户保存文档时,偶尔会发生一次。
自动保存会阻塞主队列,我的代码会在后台运行,试图读取文档,但这最终陷入了僵局,因为我无法调用主队列来创建文本附件。
我的问题是
我是否有可能忽略Xcode中的主线程检查器,并实例化 NSTextAttachmentCell
反正是在后台队列上?
我在后台队列上所做的就是初始化属性字符串及其附件。进一步的修改是在主队列上进行的。
事件的顺序
NSFileCoordinator
NSFileCoordinator
NSTextAttachmentCell
在后台队列中,让我把这个交给主队列,真正的快速...... ⚡️ DEADLOCK ⚡️ ...你不应该忽略主线程的警告。如果你使用 main.async
而非 sync
添加附件应该不会有问题。这个参考文献 也有助于定义哪些类在不同线程中表现良好。一般来说,任何AppKit视图类型的类都应该只在主线程上使用。