Jos*_*nez 2 cocoa multithreading
从后台线程将数据写入 NSPasteboard 对象是否安全?我似乎无法在任何地方找到明确的答案。我认为假设数据将在拖动开始之前写入粘贴板。
背景:
我有一个从 Evernote 获取数据的应用程序。当应用程序第一次加载时,它获取每个笔记的元数据,而不是笔记内容。然后在大纲视图中列出笔记存根。当用户开始拖动笔记时,笔记将传递到后台线程,该线程处理从 Evernote 获取笔记内容。在获取数据之前阻塞主线程会导致显着延迟和糟糕的用户体验,所以我有 [outlineView:writeItems:toPasteboard:]函数返回YES而后台线程处理数据并调用主线程将数据写入粘贴板对象。如果笔记内容在用户将笔记放在某个地方之前被传输,那么一切都会完美无缺。如果用户在处理数据之前将笔记放在某个地方......好吧,一切都会永远阻塞。仅让后台线程将数据写入粘贴板是否安全?
您可以向粘贴板承诺数据,而实际上还没有数据。
一种方法是申报的数据类型的纸板,传递自己作为剪贴板的所有者,并响应一个pasteboard:provideDataForType:消息通过提供数据(阻塞,如果必要的话,直到到达或无法到达的数据)。这意味着您需要记住复制了哪些对象(例如,通过将它们存储在数组中),以便在承诺到期时从中提取/生成数据。
另一种方式,在 Harald Scheirich 的回答中引用,是使您的模型对象符合NSPasteboardWriting 协议,理想情况下在一个类别中(将独立于接口的逻辑与特定于 Mac 的逻辑分开)。这比旧方式要干净得多,但需要 Mac OS X 10.6 及更高版本。
随着NSPasteboardWriting,你会被具有模型对象的实现诺言writingOptionsForType:pasteboard:方法返回的NSPasteboardWritingPromised选项。他们的方法将返回数据,或者至少尝试——和以前一样,这个方法应该阻塞,直到数据到达或未能到达。 pasteboardPropertyListForType:
哦,还有回答标题中的问题(“NSPasteboard 线程安全吗?”):线程安全摘要中没有具体的答案,但有一个一般性声明:
...可变对象通常不是线程安全的。要在线程应用程序中使用可变对象,应用程序必须适当地同步。
我认为 NSPasteboard 是一个可变对象,所以不是。
在实践中,这不是问题:您通常只使用 NSPasteboard 来响应操作消息(例如,copy:)、拖动或服务调用,并且无论如何这些都只发生在主线程上。为了让它们发生在辅助线程上,您必须自己从辅助线程上运行的代码中明确发送此类消息,在这种情况下,您已经在做一些非常错误的事情。
| 归档时间: |
|
| 查看次数: |
679 次 |
| 最近记录: |