2010-08-12 90 views

回答

17

CFGetTypeID()

if (CFGetTypeID(myObjectRef) == CFStringGetTypeID()) { 
    //i haz a string 
} 
+1

是的,CFType的其余部分呢?有很多,不能为每个人做。 – 2010-08-12 21:23:13

+0

其实它是一个字符串。 – 2010-08-12 21:27:35

9

简短的回答是,你可以(见戴夫DeLongs答案)。长的答案是你不能。两者都是事实。更好的问题可能是“你为什么需要知道?”在我看来,如果你能安排一些你不需要知道的事情,你可能会变得更好。

我不是说你做不到,或者你不应该做。我说的是,当你开始沿着这条路走时,会有一些隐藏的陷阱,有时候你并没有真正意识到所有没有说明的假设。不幸的是,编程正确取决于知道所有的小细节。把我的头顶部,这里有几个潜在的陷阱:

  • 要尽我所知的一套核心基金类型中的每个主要的OS版本有所增加。因此,每个主要的操作系统版本都有以前版本的超级核心基础类型,并且可能是一个严格的超集。这是“观察到的行为”,并不一定是“有保证”的行为。重要的是要注意“事情可以并且确实会改变”,并且所有事情都是平等的,更简单和更简单的解决方案往往不会考虑到这一点。一般认为编程风格很差,因此无论其原因或理由如何,都可以编写将来会破解的内容。

  • 由于核心地基与基础之间的免费电话桥接的,仅仅因为一个CFTypeRef = CFStringRef并不意味着一个CFTypeRef ≡ CFStringRef,其中=的意思是“等于”和意思是“相同的”。有一个区别,根据具体情况可能会或可能不重要。作为警告,这往往是虫子自由漫游的地方。

    例如,可以使用CFMutableStringRef,其中可以使用CFStringRef或使用CFStringRef = CFMutableStringRef。但是,您无法在任何地方使用CFStringRef,因为显而易见的原因,可以使用CFMutableStringRef。这意味着CFStringRef ≢ CFMutableStringRef。再次,根据上下文,它们可以相等,但它们不相同。

    要注意的是,虽然有一个CFStringGetTypeID(),也没有相应的CFMutableStringGetTypeID()这是非常重要。

  • 逻辑上,CFMutableStringRefCFStringRef的严格超集。然后,如果传递一个真正的不可变的CFStringRef到一个CFMutableString API调用会导致“某种问题”。虽然现在可能不是这样(例如10.6),但我知道以下事实:过去的CFMutableString API调用并未验证“字符串参数”实际上是可变的(实际上对于所有区分不可变和可变的类型)。检查在那里,但它们是在“发布”版本上被禁用的调试断言的形式(换句话说,检查从未在实践中执行过)。

    这是(或者可能是)正式不被认为是一个错误,和(琐碎)易变性检查都是做“出于性能的考虑”。没有提供“public”API来指示指针(或任何类型的可变性)的易变性。与免费桥接相结合,这意味着即使NSMutableString API确实执行了可变性检查,并在尝试变更不可变对象时导致“某种问题”,您也可以改变不可变的NSString对象。事实上,源代码中的@""常量字符串在运行时映射到只读内存。我记得,官方的一句话是“不要将不可变的对象,CFStringRef或NSString,传递给CFMutableString API,更重要的是,这是一个错误。”当有人指出这种立场可能存在一些与安全有关的问题时(不要介意这是根本不可能的事实),如果有任何事情发生了严重错误,这取决于字符串的不变性,尤其是“众所周知的”字符串,答案是“这个问题是理论上的,在这个时候没有任何工作要做,直到可以证明可行的利用。”

    更新:我很好奇,看看目前的行为是什么。在我的机器上运行10.6.4,使用CFMutableString的API在不可变的CFString上导致不可变的字符串本质上变为@"",这至少比以前更好(< = 10.5),并且实际上会改变字符串。绝对不是理想的解决方案,它具有这种苦涩的现实世界的味道,它唯一的救赎品质是它是“最差的解决方案”。

所以记住,小心你的假设!你可以做到这一点,但如果你这样做,更重要的是你不是做它错误。 :)当然,很多“错误”的解决方案都可以工作,所以事情正在发挥作用的事实并不一定证明你做得对。美好时光!

另外,在Duck Typed系统中,它经常被认为是错误的形式,甚至可能是一个错误,“过于密切地关注对象的类型”。 Objective-C绝对是一个Duck Typed系统,由于免费桥接的紧密耦合,这毫无疑问会渗透到Core Foundation中。 CFTypeRef是这种Duck Type歧义的直接表现形式,并且在很大程度上取决于上下文,可能是一种明确的方式来表达“你不应该仔细观察类型”。

+0

哇,这是一个很长的答案。 +1 – 2010-08-13 01:13:56

+1

我需要知道的原因是因为我从IO注册表中检索一个属性,这可能是一些事情,我无法确定它是什么。 – 2010-08-13 01:14:53

0

如果您想了解开发过程中CFTypeRef的类型,可以使用以下代码片段。

printf("CFTypeRef type is: %s\n",CFStringGetCStringPtr(CFCopyTypeIDDescription(CFGetTypeID(myObjectRef)),kCFStringEncodingUTF8)); 

这将打印一个人类可读的类型名称,以便知道它是什么。但Apple不保证他们会保持这些描述的一致性,因此不要在生产代码中使用它。 (正如该片段将泄漏内存,但你应该只在开发过程中使用它,所以谁在乎)。