Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 避免使用NSPasteboardItemDataProvider阻塞NSDragingSession中的主线程_Macos_Cocoa_Nspasteboard_Nsdraggingitem - Fatal编程技术网

Macos 避免使用NSPasteboardItemDataProvider阻塞NSDragingSession中的主线程

Macos 避免使用NSPasteboardItemDataProvider阻塞NSDragingSession中的主线程,macos,cocoa,nspasteboard,nsdraggingitem,Macos,Cocoa,Nspasteboard,Nsdraggingitem,在Mac OS X应用程序(Cocoa)中,我使用NSDraggingSession将一些图像从我的应用程序复制到其他应用程序。NSDraggingItem利用实现协议的对象NSPasteboardItemDataProvider,在用户删除数据时提供数据 在处理图像时,涉及的类型有:NSPasteboardTypePNG,kpasteboardtypefileurlove,kuttypfileurl,com.adobe.photoshop image和public.svg image。这些图像

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

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

我实现了方法
-粘贴板(粘贴板:item:provideDataForType:)
执行如下操作:

  • 如果请求的类型是
    kPasteboardTypeFileURLPromise
    ,我将获得粘贴位置,并在粘贴板中构建并设置URL字符串,其中包含将来应该写入文件的位置

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

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

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

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


有人知道实现这一目标的方法吗?

粘贴板类型的承诺通常意味着作为现有数据的一种替代格式,您希望避免在必要时转换数据所花费的时间和内存。我认为用它来推迟下载任何数据都不太合适。首先,当最终被请求下载时,下载可能会失败。另一方面,它可能需要任意长的时间,因为你现在正在挣扎


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

据我所知,单凭NSPasteboard API无法返回要写入文件的URL,但允许异步写入。我和一位苹果工程师谈过,他建议在编写文件时使用NSFileCoordinator,但并不是所有的目标应用都会遵守这一点。问题是,我需要下载并编写文件,然后才能告诉粘贴板将在哪里,因为如果我异步执行此操作,目标应用程序会在写入之前进行搜索,但什么也找不到。同步解决方案很好地遵守了执行顺序,但是阻塞了主线程。是的,这很有意义。祝你好运;这个API既旧又笨重。你可能在列表中也有一些运气。我使用数据提供商正是为了避免提前做所有额外的工作,因为我支持多种类型,直到最后一次才知道另一个应用程序会请求哪种类型。我不认为事先下载所有内容是个好主意,因为我有数百张不同类型的图像,用户可以在每次操作中请求一张具体类型的图像。正如我在文档中读到的,这是提供者数据的工作,但为了使其工作,我必须同步地完成所有工作,阻塞主线程。我想避免那样,没有办法避免。来自粘贴板服务器的请求是同步的。在从它调用的方法返回之前,您必须得到回复。你应该考虑复制粘贴是否是你需要的模型。至少,一次复制粘贴这么多不同的项目。也许允许用户在你的应用程序中只选择一件东西,并将其放在粘贴板上(下载必要的基础数据后)。