2010-08-12 94 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不保證他們會保持這些描述的一致性,因此不要在生產代碼中使用它。 (正如該片段將泄漏內存,但你應該只在開發過程中使用它,所以誰在乎)。