macos - 使用 NSPasteboardItemDataProvider 避免阻塞 NSDraggingSession 中的主线程

标签 macos cocoa nspasteboard nsdraggingitem

在 Mac OS X 应用程序 (Cocoa) 中,我使用 NSDraggingSession 将一些图像从我的应用程序复制到其他应用程序。 NSDraggingItem 利用实现协议(protocol) NSPasteboardItemDataProvider 的对象,在用户放下它时提供数据。

当我处理图像时,涉及的类型有:NSPasteboardTypePNGkPasteboardTypeFileURLPromisekUTTypeFileURLcom.adobe。 photoshop-imagepublic.svg-image。这些图像位于远程位置,因此在将它们提供到粘贴板之前,我必须从 Internet 下载它们。

我实现了方法-pasteboard(pasteboard:item:provideDataForType:),执行如下操作:

  • 如果请求的类型是kPasteboardTypeFileURLPromise,我会获取粘贴位置,并在粘贴板中构建和设置 URL 字符串以及将来应该写入文件的位置。

  • 如果请求的类型是kUTTypeFileURL,我会下载该文件,指定临时位置并将下载的文件写入该位置。然后,我在粘贴板中设置该位置的 URL 字符串。

  • 如果请求的类型是其他类型之一,我会下载该文件并在粘贴板中设置纯 NSData

所有这些操作都是在主线程上执行的,产生了一些我想消除的滞后。

我尝试在后台线程上执行这些操作,然后返回主线程在粘贴板中设置最终数据,但这不起作用,因为该方法之前已完成。

有人知道实现它的方法吗?

最佳答案

粘贴板类型的 promise 通常意味着您已经拥有的数据的替代格式,您希望避免在必要之前进行转换所花费的时间和内存。我认为用它来推迟下载任何数据根本不合适。一方面,当最终请求下载时,下载可能会失败。另一方面,这可能需要任意长的时间,正如您现在所苦苦挣扎的那样。

所以,我认为你应该提前下载数据。将其保留在内存中或保存到临时文件中。如果合适的话,使用 promise 的类型以不同的形式交付它,但提前准备好。

关于macos - 使用 NSPasteboardItemDataProvider 避免阻塞 NSDraggingSession 中的主线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32416376/

相关文章:

xcode - 集成机器人存储在哪里?

objective-c - 接受 iPhoto 或 Aperture 的拖放

swift 。如何允许将 URL 从浏览器拖动到 NSView

objective-c - 使用 NSPredicate 过滤 NSMutableArray

objective-c - NSUserDefaults 可以用来读/写系统首选项 plist 吗?

macos - 以编程方式更改 mac osx 上的代理

objective-c - 如何知道另一个 Cocoa 应用程序何时粘贴您放入通用粘贴板的项目

macos - 终端元箭头键绑定(bind)中的 emacs

swift - 后台进程作为 NSOperation 或线程来监视和更新文件

r - Preview v. Adob​​e 查看的 PDF 中带有 viridis 的颜色的奇怪外观