为什么NSPasteboard的-types不返回包含NSPasteboardItem的-types的并集?

时间:2010-07-15 20:34:01

标签: objective-c cocoa

NSPasteboard -types的文档内容为:

  

返回值

     

NSString对象的数组   包含类型的并集   为所有粘贴板声明的数据   接收器上的物品。归来了   类型按其顺序列出   宣布了。

尽管如此,我的NSPasteboard只有一个NSPasteboardItem[pboard types]返回的类型多于[item types]。谁能解释一下呢?

代码

以下是一些证明问题的代码:

- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
    NSPasteboard *pboard = [sender draggingPasteboard];

    // Prove that there's only one item
    if ([[pboard pasteboardItems] count] > 1)
        return NO;

    for (NSString* type in [pboard types])
        NSLog(@"Pasteboard type: %@", type);

    NSPasteboardItem* item = [[pboard pasteboardItems] objectAtIndex:0];

    for (NSString* type in [item types])
        NSLog(@"Item type: %@", type);

    return NO; // Ignore for example
}

输出

当我从Safari中拖动链接时,我得到以下输出:

Pasteboard type: dyn.ah62d4rv4gu8zs3pcnzme2641rf4guzdmsv0gn64uqm10c6xenv61a3k
Pasteboard type: WebURLsWithTitlesPboardType
Pasteboard type: dyn.ah62d4rv4gu8yc6durvwwaznwmuuha2pxsvw0e55bsmwca7d3sbwu
Pasteboard type: Apple URL pasteboard type
Pasteboard type: public.url
Pasteboard type: CorePasteboardFlavorType 0x75726C20
Pasteboard type: public.url-name
Pasteboard type: CorePasteboardFlavorType 0x75726C6E
Pasteboard type: public.utf8-plain-text
Pasteboard type: NSStringPboardType
Item type: dyn.ah62d4rv4gu8zs3pcnzme2641rf4guzdmsv0gn64uqm10c6xenv61a3k
Item type: dyn.ah62d4rv4gu8yc6durvwwaznwmuuha2pxsvw0e55bsmwca7d3sbwu
Item type: public.url
Item type: public.url-name
Item type: public.utf8-plain-text

狂野猜测

看起来[item types]基本上显示与[pboard types]相同的类型,但只显示UTI版本。由于[pboard types]似乎是将UTI类型与相应的其他类型(?)类型交错,因此它基本上是一个映射......

我可以通过简单地将UTI用于我想要的数据格式来忽略这个问题,但我正在寻找WebURLsWithTitlesPboardType(对应于dyn.ah62d4rv4gu8zs3pcnzme2641rf4guzdmsv0gn64uqm10c6xenv61a3k),我对这些问题保持警惕{ {1}} UTI。听起来像是不应硬编码的东西。

是否有可靠的方法将dyn.(...) - 样式标识符转换为UTI?我不相信实际使用WebURLsWithTitlesPboardType作为映射的方法......

3 个答案:

答案 0 :(得分:5)

我确信NSPasteboard -types的文档实际上有问题。正确的文档应该是这样的:

  

一组NSString个对象,包含为接收器上的所有粘贴板项声明的数据类型的并集,添加了旧式非UTI类型标识符。

如果您的目标是OS X 10.6+,则应该能够完全忽略NSPasteboard的{​​{1}},并且只关注每个-types的{​​{1}},但这需要专门与UTI合作。

要将非UTI类型标识符转换为UTI,您需要使用NSPasteboardItem函数;您还需要知道您已有的标识符类型(-typesUTTypeCreatePreferredIdentifierForTag()kUTTagClassFilenameExtensionkUTTagClassMIMEType)。此类型是函数的第一个参数。第二个是标识符本身(作为kUTTagClassNSPboardType)。虽然文档表明可以将kUTTagClassOSType传递给第三个参数,但在生成这些动态UTI时实际传递CFStringRef似乎很重要。

例如,要获取具有旧式标识符“WebURLsWithTitlesPboardType”的数据的(动态)UTI:

NULL

答案 1 :(得分:2)

您可以尝试使用UTTypeCreatePreferredIdentifierForTag()函数来查看是否会检索与该pboard类型对应的UTI。您可以将kUTTagClassNSPboardType传递给tagClass参数,将pboard类型传递给标记(第三个参数可以为NULL)。文档暗示这可能会返回动态UTI,因为对于WebURLsWithTitlesPboardType,任何地方都显式声明了non。目前尚不清楚的是它是否会重复使用它在粘贴板上生成的同一个,或者它是否每次都重新生成一个新的。

答案 2 :(得分:1)

这不是因为它必须保持与早期版本的Mac OS X的向后兼容性,其中没有一个是多项感知的。

如果您仅针对Mac OS X 10.6或更高版本进行开发,则可以完全忽略-types方法并直接关注粘贴板的项目。如果您的目标是Mac OS X 10.5或更早版本,则需要使用旧方法(包括-types)或在使用之前检查是否存在较新的方法和类型(通过弱链接和明智的方式)使用NSClassFromString()-respondsToSelector:。)