Objective c 为什么';t NSPasteboard';s-类型返回包含的NSPasteboardItem的并集';s型?
Objective c 为什么';t NSPasteboard';s-类型返回包含的NSPasteboardItem的并集';s型?,objective-c,cocoa,Objective C,Cocoa,NSPasteboard的类型的文档如下: 返回值 NSString对象的数组 包含类型的并集的 为所有粘贴板声明的数据 接收器上的项目。返回 类型按它们的顺序列出 被宣布 尽管如此,我有一个NSPasteboard,只有一个NSPasteboardItem,[pboard types]返回的类型比[item types]返回的类型多。有人能解释一下吗 代码 以下是一些证明问题的代码: - (BOOL)performDragOperation:(id <NSDraggingInfo>
NSPasteboard
的类型的文档如下:
返回值
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
}
胡思乱想
看起来[item types]
基本上显示了与[pboard types]
相同的类型,但只显示了UTI版本。由于[pboard types]
似乎将UTI类型与相应的其他类型(?)交错,因此它基本上是一个映射
通过简单地将UTI用于我想要的数据格式,我可能会忽略这个问题,但我正在寻找weburlswithtitlespoardtype
(对应于dyn.ah62d4rv4gu8zs3pcnzme2641rf4guzdmsv0gn64uqm10c6xenv61a3k
),我对那些dyn.(…
UTI)很警惕。听起来不应该硬编码
是否有可靠的方法将weburlswithtitlespoardtype
样式的标识符转换为UTI?我不相信实际使用[pboard types]
作为映射的方法…您可以尝试使用UTTypeCreatePreferredIdentifierForTag()
函数来查看是否会检索对应于该pboard类型的UTI。您将为tagClass参数传递kUTTagClassNSPboardType
,并将pboard类型作为标记(第三个参数可以为NULL)。这些文档暗示这可能会返回一个动态UTI,因为对于WebURLsWithTitlesPboardType,在任何地方都显式声明了non。目前尚不清楚的是,它是否会重复使用它生成的用于粘贴板的同一个版本,或者每次只是制作一个新版本。不是这样,因为它必须保持与Mac OS X早期版本的向后兼容性,这些版本都不支持多项目
如果您仅为Mac OS X 10.6或更高版本开发,则可以完全忽略-types
方法,直接关注粘贴板的项目。如果您的目标是Mac OS X 10.5或更早版本,则需要使用旧方法(包括-types
)或在使用它们之前检查是否存在较新的方法和类型(通过弱链接和明智地使用NSClassFromString()
和-respondsToSelector:
)我确信NSPasteboard
的-类型的文档实际上是错误的。正确的文档应该类似于:
一个NSString
对象数组,包含为接收器上所有粘贴板项目声明的数据类型的联合,并添加了旧式的非UTI类型标识符
如果您的目标是OS X 10.6+,您应该能够完全忽略NSPasteboard的-type
,只关注每个NSPasteboardItem的-type
,但这需要专门使用UTI
要将非UTI类型标识符转换为UTI,需要使用UTTypeCreatePreferredIdentifierForTag()
函数;您还需要知道您已经拥有哪种类型的标识符(kUTTagClassFilenameExtension
,kUTTagClassMIMEType
,KuttagClassInspBoardType
或kUTTagClassOSType
)。此类型是函数的第一个参数。第二个是标识符本身(作为CFStringRef
)。虽然文档建议第三个参数可以传递NULL
,但在生成这些动态UTI时,实际传递kUTTypeData
似乎很重要
例如,要获取具有旧式标识符“WebURLsWithTitlesPboardType”的数据的(动态)UTI:
我不确定我是否理解你第一句话的逻辑。我可以理解为什么[pboard types]
方法需要返回与[[pboard pasteboardItems]objectAtIndex:0]types]
相同的类型列表,以保持向后兼容性(甚至是项目类型的交集),但这里并不是这样。NSPasteboard
是广告类型,没有任何NSPasteboardItem
对象报告。基本上,粘贴板内容的格式在10.6中发生了变化,但只有在使用新的API的情况下。为了保持软件和API级别与旧软件的兼容性,仍然使用旧格式。格式上的区别在于,新的基本上是一个只使用UTI的俱乐部,而旧的是一个什么都可以说的俱乐部。我认为你理论上是正确的,但是你不同意苹果的文档在NSPasteboard
的-类型方面必须是错误的吗?想象一个有两个项目的粘贴板。第一项有-类型
A和B。第二项有-类型
B和C。粘贴板(每个文档)应报告-类型
A、B和C(类型的联合)。期待10.6之前行为的用户可能会从粘贴板上请求格式为C的数据,但由于粘贴板会尝试从第一个项目获取数据,因此尽管有广告,该数据仍然不可用。理论上这是理想的,但实用主义获胜。假定访问NSPasteboard
实例而不是NSPasteboardItem
实例内容的程序员正在使用旧API及其旧需求和旧数据类型。过渡到
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
CFStringRef webURLsWithTitlesUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassNSPboardType, CFSTR("WebURLsWithTitlesPboardType"), kUTTypeData);