NSPasteboard和简单的自定义数据

时间:2011-08-30 13:11:37

标签: cocoa macos nspasteboard

我真的很难让NSPasteboard工作,所以原谅我缺乏理解。

我想要的只是一种从粘贴板中编写和检索仅适用于我的应用程序的NSUInteger值的简单方法。我正在做的就是拖动我的应用程序中的项目,所以我在粘贴板中需要的只是项目的ID。

我已经尝试过研究NSPasteboardItemDataProvider和NSPasteboardItem以及NSData,但是他们都有这么简单的做事的复杂方式。事实上,我不知道做这么简单的事情的正确方法是什么 - 每个样本周围似乎都处理字符串类型,或者更复杂的东西。即使代码中没有警告,[NSMutable SetData]选择器似乎也不存在。

如果有人能指出我正确的方向,我将非常感激。 :)

编辑:我正在使用[dragImage ...]来帮助我进行拖动操作。

2 个答案:

答案 0 :(得分:43)

有两种方法可以使用NSPasteboard。

旧方法:自己将数据固定到电路板上

首先,您必须declare the types that you will put on the pasteboard。您还指定了一个“拥有”粘贴板的对象,这意味着这是将内容放在粘贴板上的对象。

下一步是将数据放在粘贴板上。此步骤是可选的。

“可选?!”,你问。是:如果您没有在已声明的任何类型的粘贴板上放置数据,并且粘贴板随后需要该数据(粘贴/删除),则the pasteboard will ask you (the owner) for it。这被称为承诺数据,并且当数据复制(大)或生成时很有用。

有五种方法可以将内容放在粘贴板上(除了要求它们):

  • As a string.仅适用于纯文本。粘贴板将根据需要处理将其转换为各种编码。
  • As a property list.仅适用于属性列表(是的,这是强制执行的,因此不会计算图像数组),或者可以转换为属性列表和从属性列表转换的内容。这可以包括您自己的对象,如果您在其中实现它们。
  • As raw data.适用于现有数据类型,例如图像类型(PNG,JPEG等)和A / V类型(MPEG-4等)。
  • As the contents of a file identified by path.只有当您拖动/复制的内容已经是文件时才有用。
  • As the contents of a file wrapper.如果您还没有使用文件包装器,则可以放心地忽略它。

更新的方法:将对象固定到电路板上,然后让它们自己变成数据

Snow Leopard中引入的新热点是让您的对象自己能够将自己写入粘贴板。这确实要求他们在粘贴板上知道关于他们自己的所有,包括标识符。

您需要使对象符合NSPasteboardWritingNSPasteboardReading

现在你知道旧的方式,写作协议看起来真的很熟悉。粘贴板会询问您的对象what types it would represent itself as,然后asks it for a property-list object for each type。 (该协议还提供了一种承诺类型的方法,而不是立即请求它们的数据。)

要将符合NSPasteboardWriting的对象复制到粘贴板,请向粘贴板发送clearContents消息(以新方式需要,以旧方式可选),然后writeObjects:传递对象数组你想复制。

正如您所期望的那样,阅读协议是反向的。要粘贴,请发送粘贴板a readObjectsForClasses:options: message。粘贴板会询问每个类what types it would recognize,然后(可选)尝试instantiate one or more of them from what's on the pasteboard

这方面的缺点,特别是涉及重用标识符的地方,是它最终会破坏模型层与控制器层的分离。如果您希望它返回具有该标识符的现有对象,Your reading initializer将需要知道如何处理标识符。这意味着它需要与控制器通信(坏)或复制控制器的查找代码(更糟)。

我不知道使用新协议实现移动拖放(包括但不限于重新排序)的好方法,而不会遇到此问题。对于复制拖放(包括但不限于跨进程),它很好,因为您不需要标识符 - 只需在一端生成数据并在另一端创建新副本

新方法的优点是处理多件物品更加清晰。在旧的方式中,只有一个“项目” - 实际上,并不是任何项目的概念 - 在多种类型中。如果要复制或拖动多个内容,则创建一个数组并将其复制为某种类型的单个属性列表,然后从另一端的单个属性列表中重新创建/检索多个内容。较新的方式明确支持一个或多个项目;复制多件事时,只需将它们全部传递给writeObjects:

您的情况:单个NSUInteger标识符

将其装入NSNumber(属性列表)并以较旧的方式使用它。

答案 1 :(得分:1)

要跟踪Peter Hosey,请回答我的GitHub PlaylistViewController.swift端口的Helium。此模块处理自定义对象的拖放以及与WKWebView的交互。

这是一项正在进行的工作,正在进行中,采用了新的闪亮粘贴板。