NSPasteboard 有两种使用方法。
较旧的方法:自己将数据固定到板上
首先,您必须声明将放在粘贴板上的类型。您还指定了一个“拥有”粘贴板的对象,这意味着这是将内容放在粘贴板上的对象。
下一步是将数据放在粘贴板上。此步骤是可选的。
“可选的?!”,你问。是的:如果您没有将您声明的任何类型的数据放在粘贴板上,并且粘贴板随后需要该数据(粘贴/删除),那么粘贴板会向您(所有者)询问它。这被称为有希望的数据,当数据的复制(大)或生成成本很高时,这很好。
有五种方法可以将东西放在粘贴板上(除了被要求提供):
- 作为一个字符串。仅适用于纯文本。粘贴板将根据需要处理将其转换为各种编码。
- 作为属性列表。仅适用于属性列表(是的,这是一直强制执行的,因此图像数组不计算在内),或者您可以与属性列表相互转换的东西。这可以包括您自己的对象,如果您在其中实现它。
- 作为原始数据。适用于现有数据类型,例如图像类型(PNG、JPEG 等)和 A/V 类型(MPEG-4 等)。
- 作为由路径标识的文件的内容。仅当您拖动/复制的内容已经是文件时才好。
- 作为文件包装器的内容。如果你还没有使用文件包装器,你可以放心地忽略它。
较新的方法:将对象固定到板上并让它们将自己变成数据
Snow Leopard 中引入的新热点是让您的对象本身能够将自己写入粘贴板。这确实要求他们了解您在粘贴板上想要的所有关于他们自己的信息,包括标识符。
您需要使您的对象同时符合NSPasteboardWriting和NSPasteboardReading。
既然您知道了旧的方式,那么编写协议看起来会非常熟悉。粘贴板询问您的对象它将自己表示为什么类型,然后向它询问每种类型的属性列表对象。(该协议还提供了一种承诺类型的方法,而不是立即请求它们的数据。)
要将符合 NSPasteboardWriting 的对象复制到粘贴板,请向粘贴板发送一条clearContents
消息(在新方式中是必需的,在旧方式中是可选的),然后writeObjects:
传递要复制的对象数组。
如您所料,阅读协议是相反的。要粘贴,请向粘贴板发送一条readObjectsForClasses:options:
消息。粘贴板询问这些类中的每一个它会识别什么类型,然后(可选地)尝试从粘贴板上的内容实例化它们中的一个或多个。
这样做的缺点是,特别是在涉及重用标识符的情况下,它最终可能会破坏模型层与控制器层的分离。如果您希望它返回具有该标识符的现有对象,您的读取初始化程序将需要知道如何处理该标识符。这意味着它需要与控制器对话(不好)或复制控制器的查找代码(更糟)。
我不知道使用新协议实现移动拖放(包括但不限于重新排序)而不遇到此问题的好方法。对于复制拖放(包括但不限于跨进程),这很好,因为您不需要标识符 - 只需在一端生成数据并在另一端创建新副本.
新方法的好处是处理多个项目更加理智。在旧的方式中,只有一个“项目”——实际上,根本没有任何项目的概念——有多种类型。如果您想复制或拖动多个事物,您可以创建一个数组并将其复制为某种类型的单个属性列表,然后在另一端从该单个属性列表中重新创建/检索多个事物。较新的方式明确支持一个或多个项目;复制多个东西时,您只需将它们全部传递给writeObjects:
.
您的案例:单个 NSUInteger 标识符
将它装在一个 NSNumber (这是一个属性列表)中,并以旧的方式使用它。