NSPasteboard和简单的自定义数据

And*_*ang 17 macos cocoa nspasteboard

我正在努力让NSPasteboard工作,所以原谅我缺乏理解.

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

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

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

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

Pet*_*sey 44

有两种方法可以使用NSPasteboard.

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

首先,您必须声明要放在粘贴板上的类型.您还指定了一个"拥有"粘贴板的对象,这意味着这是将内容放在粘贴板上的对象.

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

"可选?!",你问.是的:如果您没有在已声明的任何类型的粘贴板上放置数据,并且粘贴板随后需要该数据(粘贴/删除),则粘贴板将询问您(所有者).这被称为承诺数据,并且当数据复制(大)或生成时很有用.

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

  • 作为一个字符串.只适用于纯文本.粘贴板将根据需要处理将其转换为各种编码.
  • 作为财产清单.仅适用于属性列表(是的,这一直强制执行,因此不会计算图像数组),或者可以转换为属性列表和从属性列表转换的内容.这可以包括您自己的对象,如果您在其中实现它们.
  • 作为原始数据.适用于现有数据类型,如图像类型(PNG,JPEG等)和A/V类型(MPEG-4等).
  • 作为路径标识的文件的内容.只有当您拖动/复制的内容已经是文件时才有用.
  • 作为文件包装器的内容.如果您还没有使用文件包装器,则可以放心地忽略它.

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

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

您需要使对象符合NSPasteboardWritingNSPasteboardReading.

由于你知道旧的方式,写协议看起来真的很熟悉.粘贴板会询问您的对象它将表示自己的类型,然后要求它为每种类型的属性列表对象.(该协议还提供了一种承诺类型的方法,而不是立即请求它们的数据.)

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

正如您所期望的那样,读取协议是反向的.要粘贴,您可以向粘贴板发送一条readObjectsForClasses:options:消息.粘贴板向每个类询问它将识别哪些类型,然后(可选)尝试从粘贴板上的内容实例化其中一个或多个类.

这种情况的缺点,特别是在重用标识符的情况下,最终会破坏模型层与控制器层的分离.如果您希望它返回具有该标识符的现有对象,则您的读取初始化程序将需要知道如何处理标识符.这意味着它需要与控制器通信(坏)或复制控制器的查找代码(更糟糕).

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

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

您的情况:单个NSUInteger标识符

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

  • 不幸的是,Apple更改了URL,几乎所有链接都转到了同一个通用页面. (3认同)