CoreFoundation框架詳細(xì)解析(二) —— 設(shè)計(jì)概念

版本記錄

版本號(hào) 時(shí)間
V1.0 2017.10.06

前言

Core Foundation框架(CoreFoundation.framework)是一組C語(yǔ)言接口廓脆,它們?yōu)閕OS應(yīng)用程序提供基本數(shù)據(jù)管理和服務(wù)功能飞蛹。接下來(lái)我們就詳細(xì)的解析這個(gè)框架瞧栗。感興趣的可以看我上面寫的幾篇酪劫。
1. CoreFoundation框架詳細(xì)解析(一) —— 基本概覽

簡(jiǎn)介

Core Foundation是一個(gè)庫(kù)啊犬,具有一系列概念性的基于Objective-C的基礎(chǔ)框架扩所,但以C語(yǔ)言實(shí)現(xiàn)的編程接口虎锚。 為此硫痰,Core Foundation在C中實(shí)現(xiàn)了有限的對(duì)象模型。Core Foundation定義了封裝數(shù)據(jù)和函數(shù)的不透明類型窜护,以下稱為“對(duì)象”效斑。

Core Foundation對(duì)象的編程接口設(shè)計(jì)為易于使用和重用。 一般來(lái)說(shuō)柱徙,Core Foundation:

  • 支持在各種框架和庫(kù)之間共享代碼和數(shù)據(jù)
  • 使一定程度的操作系統(tǒng)獨(dú)立成為可能
  • 支持Unicode字符串的國(guó)際化
  • 提供通用的API和其他有用功能缓屠,包括插件架構(gòu),XML屬性列表和首選項(xiàng)

Core Foundation使OS X上的不同框架和庫(kù)可以共享代碼和數(shù)據(jù)坐搔。 應(yīng)用程序藏研,庫(kù)和框架可以定義在其外部接口中并入Core Foundation類型的C例程;因此它們可以通過(guò)這些接口將數(shù)據(jù)(作為Core Foundation對(duì)象)傳遞給彼此概行。

Core Foundation會(huì)還提供某些服務(wù)與Cocoa’s Foundation框架之間的toll-free bridging - 免費(fèi)橋接蠢挡。 免費(fèi)橋接使您可以將Cocoa對(duì)象替換為功能參數(shù)中的Core Foundation對(duì)象,反之亦然凳忙。

一些Core Foundation的類型和函數(shù)是在不同操作系統(tǒng)上具有特定實(shí)現(xiàn)的東西的抽象业踏。使用這些API的代碼因此更容易移植到不同的平臺(tái)。

Datenumber類型抽象時(shí)間工具涧卵,并提供在絕對(duì)和公歷時(shí)間之間進(jìn)行轉(zhuǎn)換的設(shè)施勤家。它還抽象數(shù)值,并提供了在這些值的不同內(nèi)部表示之間進(jìn)行轉(zhuǎn)換的工具柳恐。

Core Foundation為應(yīng)用程序開發(fā)帶來(lái)的主要優(yōu)點(diǎn)之一是國(guó)際化支持伐脖。通過(guò)其String對(duì)象,Core Foundation可以在所有OS X和Cocoa編程接口和實(shí)現(xiàn)方面實(shí)現(xiàn)輕松乐设,強(qiáng)大和一致的國(guó)際化讼庇。此支持的基本部分是CFString類型,其實(shí)例表示16位Unicode字符數(shù)組近尚。 CFString對(duì)象具有足夠的靈活性蠕啄,可以容納數(shù)字字符,并且簡(jiǎn)單而低級(jí),足以用于傳送字符數(shù)據(jù)的所有編程接口歼跟。它的性能與標(biāo)準(zhǔn)C字符串的性能沒有太大的不同和媳。

您應(yīng)該閱讀本文檔,以了解Core Foundation以及Core Foundation對(duì)象與Cocoa (Touch)對(duì)象交互的基本設(shè)計(jì)原則哈街。


Organization of This Document - 文檔的組成

這些概念和任務(wù)討論了在Core Foundation中使用的對(duì)象模型留瞳。

此外,還有其他非對(duì)象類型和API約定叹卷,您應(yīng)該在使用Core Foundation之前熟悉它們:


Opaque Types - 不透明類型

Core Foundation的支持封裝和多態(tài)函數(shù)的對(duì)象模型基于不透明類型撼港。

基于不透明類型的對(duì)象的各個(gè)字段從客戶端隱藏,但類型的函數(shù)提供對(duì)這些字段的大多數(shù)值的訪問(wèn)骤竹。Figure 1描繪了它隱藏的數(shù)據(jù)中的不透明類型和它呈現(xiàn)給客戶端的接口。

注意:“Class”不用于引用不透明類型往毡,因?yàn)楸M管類和不透明類型有概念上的相似性蒙揣,但很多人可能會(huì)發(fā)現(xiàn)術(shù)語(yǔ)混淆。然而开瞭,Core Foundation文檔經(jīng)常將這些類型的具體的數(shù)據(jù)承載實(shí)例稱為“對(duì)象”懒震。

Core Foundation會(huì)有許多不透明的類型,這些類型的名稱反映了他們的特定用途嗤详。例如个扰,CFString是一種不透明的類型,“代表”并對(duì)Unicode字符數(shù)組進(jìn)行操作葱色。 (“CF”當(dāng)然是Core Foundation的前綴递宅。),CFArray是基于索引的收集功能的不透明類型苍狰。支持不透明類型的函數(shù)办龄,常量和其他輔助數(shù)據(jù)類型通常在具有類型名稱的頭文件中定義,例如淋昭,CFArray.h包含CFArray類型的符號(hào)定義俐填。

Figure 1 An opaque type

1. Advantages of Opaque Types - 不透明類型的優(yōu)點(diǎn)

對(duì)某些來(lái)說(shuō),不透明的類型似乎是通過(guò)阻止結(jié)構(gòu)內(nèi)容的直接訪問(wèn)來(lái)施加不必要的限制翔忽。與可能影響程序性能的不透明類型似乎也有開銷英融。但是不透明類型的好處超過(guò)了這些看似的限制。

不透明類型為底層功能的實(shí)現(xiàn)提供了更好的抽象和更大的靈活性歇式。通過(guò)隱藏諸如結(jié)構(gòu)體領(lǐng)域的細(xì)節(jié)驶悟,當(dāng)這些細(xì)節(jié)發(fā)生變化時(shí),Core Foundation可以減少客戶端代碼中可能發(fā)生的錯(cuò)誤的機(jī)會(huì)贬丛。此外唠叛,不透明類型允許優(yōu)化,如果暴露可能會(huì)令人困惑垛叨。例如,CFString“正式”表示UniChar類型的16位字符數(shù)組够庙。但是,CFString可能會(huì)選擇將ASCII范圍內(nèi)的一系列字符存儲(chǔ)為8位值抄邀。復(fù)制一個(gè)不可變對(duì)象可能(通常會(huì))導(dǎo)致對(duì)對(duì)象的共享引用耘眨,而不是存儲(chǔ)器中的兩個(gè)單獨(dú)的對(duì)象(參見Memory Management Programming Guide for Core Foundation)。

繼續(xù)使用CFString的示例境肾,使用不透明類型存儲(chǔ)字符可能看起來(lái)很重剔难。然而,事實(shí)證明奥喻,這種存儲(chǔ)的CPU成本并不比使用簡(jiǎn)單的C數(shù)組字符高得多偶宫,并且內(nèi)存成本通常較少。此外环鲤,不透明度并不一定意味著不透明類型不能直接提供訪問(wèn)內(nèi)容的機(jī)制纯趋。例如,CFString為此提供了CFStringGetCStringPtr函數(shù)冷离。

最后吵冒,您可以在一定程度上自定義一些不透明類型。例如西剥,集合類型允許您定義用于在集合的每個(gè)成員上調(diào)用函數(shù)的回調(diào)痹栖。


Object References - 對(duì)象引用

您可以通過(guò)引用來(lái)引用Core Foundation對(duì)象(不透明類型)。 在不透明類型的每個(gè)頭文件中瞭空,您將注意到一行或兩行類似于以下內(nèi)容:

typedef const struct __CFArray * CFArrayRef;
typedef struct __CFArray * CFMutableArrayRef;

這些聲明是指向不透明和可變版本的(專用)結(jié)構(gòu)定義不透明類型的指針引用揪阿。 許多Core Foundation函數(shù)的參數(shù)和返回值都是這些對(duì)象引用的類型,而不是私有結(jié)構(gòu)的typedef匙铡。 例如:

CFStringRef CFStringCreateByCombiningStrings(CFAllocatorRef alloc, CFArrayRef array, CFStringRef separatorString);

有關(guān)不透明類型對(duì)象的不變图甜,可變和其他變體的更多信息,請(qǐng)參閱Varieties of Objects鳖眼。

每個(gè)Core Foundation 不透明類型為其對(duì)象定義唯一的類型ID黑毅,如CFArray對(duì)象的CFArrayRef中所示。類型ID是類型為CFTypeID的整數(shù)钦讳,用于標(biāo)識(shí)Core Foundation對(duì)象“belongs”的不透明類型矿瘦。您可以在各種上下文中使用類型ID,例如在異構(gòu)集合上運(yùn)行時(shí)愿卒。 Core Foundation提供用于獲取和評(píng)估類型ID的編程接口缚去。

重要提示:由于類型ID的值可以在釋放中更改,您的代碼不應(yīng)該依賴存儲(chǔ)的或硬編碼的類型ID琼开,也不應(yīng)該對(duì)所有觀察到的類型ID的屬性進(jìn)行硬編碼(例如易结,它是一個(gè)小整數(shù))。

此外,Core Foundation定義了一種通用對(duì)象引用類型CFTypeRef搞动,類似于某些面向?qū)ο缶幊陶Z(yǔ)言中的根類躏精。此通用引用用作多項(xiàng)式函數(shù)的參數(shù)和返回值的占位符類型,可以引用任何Core Foundation對(duì)象鹦肿。有關(guān)此主題的更多信息矗烛,請(qǐng)參閱Polymorphic Functions 。有關(guān)使用對(duì)象引用時(shí)與內(nèi)存管理相關(guān)的問(wèn)題箩溃,請(qǐng)參閱Memory Management Programming Guide for Core Foundation瞭吃。


Polymorphic Functions - 多態(tài)函數(shù)

Core Foundation提供了幾個(gè)多態(tài)函數(shù)。這些函數(shù)可以將任何Core Foundation對(duì)象作為參數(shù)涣旨,并且(在一個(gè)實(shí)例中歪架,CFRetain)可以返回任何Core Foundation對(duì)象。給定這些參數(shù)和返回值的類型為CFTypeRef开泽,一般的對(duì)象引用類型牡拇。CFType類似于面向?qū)ο笳Z(yǔ)言中的根類,因?yàn)樗墓δ芸梢员凰衅渌麑?duì)象重用穆律。

您對(duì)所有Core Foundation對(duì)象常見的操作使用多態(tài)函數(shù):

  • 參考計(jì)數(shù)。

  • 比較對(duì)象

    • CFEqual函數(shù)比較任何兩個(gè)Core Foundation對(duì)象(請(qǐng)參見Comparing Objects)旅薄。平等的依據(jù)取決于比較對(duì)象的類型辅髓。例如,如果兩者都是CFString對(duì)象少梁,則測(cè)試涉及逐個(gè)字符的比較洛口。
  • 哈希對(duì)象。

    • CFHash函數(shù)返回標(biāo)識(shí)Core Foundation對(duì)象的唯一哈希碼(請(qǐng)參閱 Comparing Objects)凯沪。您可以使用哈希碼作為哈希表結(jié)構(gòu)中的表地址第焰。如果兩個(gè)對(duì)象相等(由CFEqual函數(shù)確定),則它們必須具有相同的哈希值妨马。
  • 檢查對(duì)象挺举。

    • CFType為您提供檢查對(duì)象的方法,從而了解其內(nèi)容及其所屬類型烘跺。CFCopyDescription函數(shù)返回描述對(duì)象的字符串(更準(zhǔn)確地說(shuō)湘纵,是對(duì)CFString對(duì)象的引用)。使用CFTypeID而不是CFTypeRef參數(shù)的CFCopyTypeIDDescription函數(shù)返回一個(gè)字符串引用滤淳,該引用描述了類型ID標(biāo)識(shí)的不透明類型梧喷。這些函數(shù)主要用于協(xié)助調(diào)試,有關(guān)這些功能的更多信息,請(qǐng)參閱Inspecting Objects铺敌。

您還可以通過(guò)使用CFGetTypeID函數(shù)獲取其類型ID汇歹,然后將該值與已知類型ID進(jìn)行比較,來(lái)確定通用類型對(duì)象所屬的opaque類型适刀。有關(guān)此任務(wù)的更多信息秤朗,請(qǐng)參閱Inspecting Objects


Varieties of Objects - 對(duì)象種類

根據(jù)其對(duì)象中預(yù)期的可編輯性和可擴(kuò)展性的特點(diǎn)笔喉,不透明類型最多可以有三種基本種類取视,或flavor

  • 不變的和固定的大小
  • 可變和固定尺寸
  • 可變和可變大小

可變對(duì)象是可編輯的常挚,意味著可以更改其內(nèi)容作谭。不可變對(duì)象不可編輯,一旦創(chuàng)建奄毡,他們就不能改變折欠。任何改變不可變對(duì)象的嘗試通常都會(huì)導(dǎo)致某種錯(cuò)誤。固定大小的對(duì)象具有可以增長(zhǎng)到的最大限制吼过,在CFString的情況下锐秦,這將是字符數(shù),對(duì)于集合盗忱,限制將是元素的數(shù)量酱床。

一些不透明的類型,如CFString和CFArray趟佃,可以創(chuàng)建所有三種風(fēng)格的對(duì)象扇谣。大多數(shù)不透明類型可以創(chuàng)建不變的固定大小的對(duì)象,并且通常至少有一個(gè)不合格的創(chuàng)建函數(shù)來(lái)執(zhí)行該工作(如CFArrayCreate)闲昭」拚可變固定大小與可變大小的決定因素是TypeCreateMutable函數(shù)中容量或最大長(zhǎng)度參數(shù)的值,任何正值都會(huì)導(dǎo)致固定大小的對(duì)象序矩,但是0指定可變大小的對(duì)象鸯绿。

對(duì)可變對(duì)象的引用包括類型名稱中的Mutable,例如CFMutableStringRef贮泞。


Naming Conventions - 命名約定

Core Foundation中的主要編程接口約定是使用與符號(hào)最密切相關(guān)的不透明類型的名稱作為符號(hào)的前綴楞慈。 對(duì)于函數(shù),此前綴不僅標(biāo)識(shí)函數(shù)“所屬”的類型啃擦,而且還標(biāo)識(shí)作為函數(shù)動(dòng)作目標(biāo)的對(duì)象的類型囊蓝。 (這個(gè)約定的一個(gè)例外是常量,它將“k”放在類型前綴之前令蛉。)這里是頭文件中的幾個(gè)例子:

/* from CFDictionary.h */
CF_EXPORT CFIndex CFDictionaryGetCountOfKey(CFDictionaryRef dict, const void *key);
/* from CFString.h */
typedef UInt32 CFStringEncoding;
/* from CFCharacterSet.h */
typedef enum {
    kCFCharacterSetControl = 1,
    kCFCharacterSetWhitespace,
    kCFCharacterSetWhitespaceAndNewline,
    kCFCharacterSetDecimalDigit,
    kCFCharacterSetLetter,
    kCFCharacterSetLowercaseLetter,
    kCFCharacterSetUppercaseLetter,
    kCFCharacterSetNonBase,
    kCFCharacterSetDecomposable,
    kCFCharacterSetAlphaNumeric,
    kCFCharacterSetPunctuation,
    kCFCharacterSetIllegal
} CFCharacterSetPredefinedSet;

除了與不透明類型和內(nèi)存管理相關(guān)的內(nèi)容之外聚霜,Core Foundation還有一些編程接口約定狡恬。

  • 在返回值的函數(shù)的名稱中,Get蝎宇、CopyCreate之間有一個(gè)重要區(qū)別弟劲。如果使用Get函數(shù),則無(wú)法確定返回的對(duì)象的使用壽命姥芥。為了確保這樣的對(duì)象的持久性兔乞,您可以保留它(使用CFRetain函數(shù)),或者在某些情況下復(fù)制它凉唐。如果您使用Copy或者Create函數(shù)庸追,您將負(fù)責(zé)釋放對(duì)象(使用CFRelease函數(shù))。有關(guān)更多詳細(xì)信息台囱,請(qǐng)參閱 Memory Management Programming Guide for Core Foundation淡溯。
  • 一些Core Foundation對(duì)象有自己的命名約定來(lái)強(qiáng)化常見操作之間的一致性。例如簿训,集合在函數(shù)名中嵌入以下動(dòng)詞來(lái)表示對(duì)集合元素的具體操作:
    • Add是指“如果不存在就添加咱娶,如果存在則不做任何事情”(如果是排他性的唯一的集合)。
    • Replace是指“如果存在强品,請(qǐng)更換膘侮,如果不存在則不做任何事情”。
    • Set表示“如果不存在則添加”的榛,如果存在則替換“”喻喳。
    • Remove表示“如果存在,刪除困曙,如果缺席,不做任何事情”谦去。
  • CFIndex類型用于索引慷丽,計(jì)數(shù),長(zhǎng)度和大小參數(shù)以及返回值鳄哭。當(dāng)處理器的地址大小增加時(shí)要糊,此類型表示的整數(shù)值(當(dāng)前為32位)隨著時(shí)間的推移而增長(zhǎng)。在指針大小不同的體系結(jié)構(gòu)(比如64位)上妆丘,CFIndex可能被聲明為64位锄俄,與int的大小無(wú)關(guān)。通過(guò)使用CFIndex與相同類型的Core Foundation參數(shù)進(jìn)行交互的變量勺拣,您可以確保代碼的源兼容性更高奶赠。
  • 一些Core Foundation頭文件似乎可以定義不透明類型,但實(shí)際上包含與特定類型無(wú)關(guān)的便利函數(shù)药有。一個(gè)例子是CFPropertyList.h毅戈。 CFPropertyList是任何屬性列表類型的占位符類型:CFString苹丸,CFData,CFBoolean苇经,CFNumber赘理,CFDate,CFArray和CFDictionary扇单。
  • 除非另有說(shuō)明商模,否則用于返回值的所有參考參數(shù)都可以接受NULL。這表示調(diào)用者對(duì)該返回值不感興趣蜘澜。

Other Types - 其他類型

Core Foundation定義了一些函數(shù)中使用的數(shù)據(jù)類型施流。這些類型中的一些的目的是抽象可能隨著處理器地址空間的變化而改變的原始值。例如兼都,CFIndex類型用于索引嫂沉,計(jì)數(shù),長(zhǎng)度和大小參數(shù)扮碧。CFOptionFlags類型用于位域參數(shù)趟章,CFHashCode類型保留從CFHash函數(shù)返回的散列結(jié)果和某些哈希回調(diào)慎王。

其他基本類型用于獲取并返回比較和范圍值的函數(shù)蚓土。 CFRange是一個(gè)結(jié)構(gòu),用于指定項(xiàng)目的線性序列的任何部分赖淤,從字符串中的字符到集合中的元素蜀漆。對(duì)于比較函數(shù),CFComparisonResult類型定義枚舉常量來(lái)表示適當(dāng)?shù)姆祷刂担ǖ扔谠酆担∮谌范笥冢R恍〤ore Foundation函數(shù)可以回調(diào)比較器函數(shù)吐限,如果要使用自定義比較器鲜侥,則該函數(shù)必須符合CFComparatorFunction類型指定的簽名。

重要提示:某些Core Foundation類型的整數(shù)值诸典,特別是CFIndexCFTypeID描函,可隨著處理器的地址大小的增長(zhǎng)而隨著時(shí)間的推移而增長(zhǎng)。通過(guò)使用與相同類型的Core Foundation參數(shù)交互的變量的基本類型狐粱,您將確保為代碼提供更高程度的源兼容性舀寓。

Core Foundation提供的其他不透明類型在不同的主題中討論。


Comparing Objects - 對(duì)象的比較

您使用CFEqual函數(shù)將兩個(gè)Core Foundation對(duì)象進(jìn)行比較肌蜻。 如果兩個(gè)對(duì)象基本相等互墓,該函數(shù)將返回一個(gè)布爾值true。“ Essential”相等取決于所比較的對(duì)象的類型宋欺。 例如轰豆,當(dāng)您比較兩個(gè)CFString對(duì)象時(shí)胰伍,Core Foundation認(rèn)為它們?cè)诜现饌€(gè)字符時(shí)基本相同,無(wú)論其編碼或可變性屬性如何酸休。 當(dāng)兩個(gè)CFArray對(duì)象具有相同的元素?cái)?shù)量時(shí)骂租,并且一個(gè)數(shù)組中的每個(gè)元素對(duì)象與其他數(shù)組中的對(duì)應(yīng)基本相同,它們被認(rèn)為是相等的斑司。顯然渗饮,被比較的對(duì)象必須是相同類型(或相同類型的可變或不可變變體)被認(rèn)為是相等的。

以下代碼片段顯示了如何使用CFEqual函數(shù)將常量與傳入?yún)?shù)進(jìn)行比較:

// Listing 1  Comparing Core Foundation objects

void stringTest(CFStringRef myString) {
    Boolean equal = CFEqual(myString, CFSTR(“Kalamazoo”));
    if (!equal) {
        printf(“They’re not equal!");
    }
    else {
        printf(“They’re equal!”):
    }
}

Inspecting Objects - 檢查對(duì)象

Core Foundation對(duì)象的主要特征是它們基于不透明(或私有)類型宿刮,因此難以直接檢查對(duì)象的內(nèi)部數(shù)據(jù)互站。 但是,Base Services提供了兩個(gè)函數(shù)僵缺,您可以使用它們來(lái)檢查Core Foundation對(duì)象胡桃。 這些函數(shù)返回對(duì)象和對(duì)象類型的描述。

要查找Core Foundation對(duì)象的內(nèi)容磕潮,請(qǐng)調(diào)用該對(duì)象的CFCopyDescription函數(shù)翠胰,然后在引用的字符串對(duì)象中打印包含的字符序列:

// Listing 1  Using CFCopyDescription

void describe255(CFTypeRef tested) {
    char buffer[256];
    CFIndex got;
    CFStringRef description = CFCopyDescription(tested);
    CFStringGetBytes(description,
        CFRangeMake(0, CFStringGetLength(description)),
        CFStringGetSystemEncoding(), '?', TRUE, buffer, 255, &got);
    buffer[got] = (char)0;
    fprintf(stdout, "%s", buffer);
    CFRelease(description);
}

此示例僅顯示打印描述的一種方法。 您可以使用CFStringGetBytes以外的CFString函數(shù)來(lái)獲取實(shí)際的字符串自脯。

要確定“unknown”對(duì)象的類型之景,請(qǐng)使用CFGetTypeID函數(shù)獲取其類型ID,并將該值與已知類型ID進(jìn)行比較膏潮,直到找到匹配項(xiàng)锻狗。 使用CFGetTypeID函數(shù)獲取對(duì)象的類型ID。 每個(gè)不透明類型還定義了CFTypeGetTypeID形式的函數(shù)(例如焕参,CFArrayGetTypeID)轻纪,此函數(shù)返回該類型的類型ID。 因此叠纷,您可以測(cè)試CFType對(duì)象是否是特定不透明類型的成員桐磁,如:

CFTypeID type = CFGetTypeID(anObject);
if (CFArrayGetTypeID() == type)
    printf(“anObject is an array.”);
else
    printf(“anObject is NOT an array.”);

要顯示關(guān)于調(diào)試器中Core Foundation對(duì)象類型的信息,請(qǐng)使用CFGetTypeID函數(shù)獲取其類型ID讲岁,然后將該值傳遞給CFCopyTypeIDDescription函數(shù):

/* aCFObject is any Core Foundation object */
CFStringRef descrip = CFCopyTypeIDDescription(CFGetTypeID(aCFObject));

注意:·String Services·包括兩個(gè)在·CFString.h·中聲明的函數(shù),您可以調(diào)用支持的調(diào)試器來(lái)打印Core Foundation對(duì)象的描述:CFShow和CFShowStr衬以。

要點(diǎn)CFCopyDescriptionCFCopyTypeIDDescription函數(shù)僅用于調(diào)試缓艳。 因?yàn)槊枋鲋械男畔⒑透袷娇赡軙?huì)發(fā)生變化,所以不要在代碼中創(chuàng)建依賴關(guān)系看峻。


Toll-Free Bridged Types - 自由橋接類型

Core Foundation框架中有許多數(shù)據(jù)類型可以和Foundation框架中的類型互換使用阶淘。可互換使用的數(shù)據(jù)類型也稱為自由橋接數(shù)據(jù)類型互妓。這意味著您可以使用與Core Foundation函數(shù)調(diào)用的參數(shù)相同的數(shù)據(jù)結(jié)構(gòu)作為OC消息轉(zhuǎn)發(fā)的接收方溪窒。例如坤塞,NSLocale(參見NSLocale Class Reference)可以與其Core Foundation對(duì)應(yīng)的CFLocale(參見CFLocale Reference)互換。

盡管他們的名字可能表明它們是澈蚌,但是不是所有的數(shù)據(jù)類型都是自由的橋接摹芙,例如,NSRunLoop不是自由橋接到CFRunLoop宛瞄,NSBundle不是自由橋接到CFBundle浮禾,并且NSDateFormatter不是自由橋接到CFDateFormatter。Table 1提供了支持自由橋接的數(shù)據(jù)類型的列表份汗。

注意:如果在您正在使用的Core Foundation集合上安裝的自定義回調(diào)盈电,包括NULL回調(diào),則當(dāng)從Objective-C訪問(wèn)時(shí)杯活,其內(nèi)存管理行為未定義匆帚。

1. Casting and Object Lifetime Semantics - 轉(zhuǎn)換對(duì)象終身語(yǔ)義

通過(guò)自由橋接,在您可以看到例如NSLocale *參數(shù)的方法中旁钧,您可以傳遞CFLocaleRef吸重,并且在您看到CFLocaleRef參數(shù)的函數(shù)中,可以傳遞NSLocale實(shí)例均践。 您還必須為編譯器提供其他信息:首先晤锹,必須將一種類型轉(zhuǎn)換為另一種類型;此外彤委,您可能必須指示對(duì)象生命周期語(yǔ)義鞭铆。

編譯器了解返回Core Foundation類型并遵循歷史Cocoa命名約定的Objective-C方法(請(qǐng)參閱 Advanced Memory Management Programming Guide)。 例如焦影,編譯器知道车遂,在iOS中,由UIColorCGColor方法返回的CGColor不是它所擁有的斯辰。 您仍然必須使用適當(dāng)?shù)念愋娃D(zhuǎn)換舶担,如本示例所示:

NSMutableArray *colors = [NSMutableArray arrayWithObject:(id)[[UIColor darkGrayColor] CGColor]];
[colors addObject:(id)[[UIColor lightGrayColor] CGColor]];

編譯器不會(huì)自動(dòng)管理Core Foundation對(duì)象的生命周期。 您可以使用cast(在objc / runtime.h中定義)或Core Foundation-style宏(在NSObject.h中定義)告知編譯器對(duì)象的所有權(quán)語(yǔ)義:

  • __bridge在Objective-C和Core Foundation之間傳輸一個(gè)指針彬呻,而不轉(zhuǎn)移所有權(quán)衣陶。
  • __bridge_retainedCFBridgingRetain將一個(gè)Objective-C指針轉(zhuǎn)換為Core Foundation指針,并將所有權(quán)轉(zhuǎn)讓給您闸氮。您負(fù)責(zé)調(diào)用CFRelease或相關(guān)函數(shù)以放棄該對(duì)象的所有權(quán)剪况。
  • __bridge_transferCFBridgingRelease將非Objective-C指針移動(dòng)到Objective-C,并將所有權(quán)轉(zhuǎn)移給ARC蒲跨。ARC負(fù)責(zé)放棄對(duì)象的所有權(quán)译断。

其中一些顯示在以下示例中:

NSLocale *gbNSLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"];
CFLocaleRef gbCFLocale = (__bridge CFLocaleRef)gbNSLocale;
CFStringRef cfIdentifier = CFLocaleGetIdentifier(gbCFLocale);
NSLog(@"cfIdentifier: %@", (__bridge NSString *)cfIdentifier);
// Logs: "cfIdentifier: en_GB"
 
CFLocaleRef myCFLocale = CFLocaleCopyCurrent();
NSLocale *myNSLocale = (NSLocale *)CFBridgingRelease(myCFLocale);
NSString *nsIdentifier = [myNSLocale localeIdentifier];
CFShow((CFStringRef)[@"nsIdentifier: " stringByAppendingString:nsIdentifier]);
// Logs identifier for current locale

下一個(gè)示例顯示了使用Core Foundation內(nèi)存管理函數(shù),這些功能由Core Foundation內(nèi)存管理規(guī)則指定:

- (void)drawRect:(CGRect)rect {

CGContextRef ctx = UIGraphicsGetCurrentContext();

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();

CGFloat locations[2] = {0.0, 1.0};

NSMutableArray *colors = [NSMutableArray arrayWithObject:(id)[[UIColor darkGrayColor] CGColor]];

[colors addObject:(id)[[UIColor lightGrayColor] CGColor]];

CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);

CGColorSpaceRelease(colorSpace); // Release owned Core Foundation object.

CGPoint startPoint = CGPointMake(0.0, 0.0);

CGPoint endPoint = CGPointMake(CGRectGetMaxX(self.bounds), CGRectGetMaxY(self.bounds));

CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint,

kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);

CGGradientRelease(gradient); // Release owned Core Foundation object.

}

2. Toll-Free Bridged Types - 自由橋接類型

Table 1提供了Core Foundation和Foundation之間可互換的數(shù)據(jù)類型列表或悲。 對(duì)于每一對(duì)孙咪,該表還列出了它們之間的自由橋接可用的OS X版本堪唐。

Core Foundation type Foundation class Availability
CFArrayRef NSArray OS X 10.0
CFAttributedStringRef NSAttributedString OS X 10.4
CFBooleanRef NSNumber OS X 10.0
CFCalendarRef NSCalendar OS X 10.4
CFCharacterSetRef NSCharacterSet OS X 10.0
CFDateRef NSDate OS X 10.0
CFDictionaryRef NSDictionary OS X 10.0
CFErrorRef NSError OS X 10.5
CFLocaleRef NSLocale OS X 10.4
CFMutableArrayRef NSMutableArray OS X 10.0
CFMutableAttributedStringRef NSMutableAttributedString OS X 10.4
CFMutableCharacterSetRef NSMutableCharacterSet OS X 10.0
CFMutableDataRef NSMutableData OS X 10.0
CFMutableDictionaryRef NSMutableDictionary OS X 10.0
CFMutableSetRef NSMutableSet OS X 10.0
CFMutableStringRef NSMutableString OS X 10.0
CFNullRef NSNull OS X 10.2
CFNumberRef NSNumber OS X 10.0
CFReadStreamRef NSInputStream OS X 10.0
CFRunLoopTimerRef NSTimer OS X 10.0
CFSetRef NSSet OS X 10.0
CFStringRef NSString OS X 10.0
CFTimeZoneRef NSTimeZone OS X 10.0
CFURLRef NSURL OS X 10.0
CFWriteStreamRef NSOutputStream OS X 10.0

后記

未完,待續(xù)~~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末翎蹈,一起剝皮案震驚了整個(gè)濱河市淮菠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌杨蛋,老刑警劉巖兜材,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異逞力,居然都是意外死亡曙寡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門寇荧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)举庶,“玉大人,你說(shuō)我怎么就攤上這事揩抡』Ы模” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵峦嗤,是天一觀的道長(zhǎng)蕊唐。 經(jīng)常有香客問(wèn)我,道長(zhǎng)烁设,這世上最難降的妖魔是什么替梨? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮装黑,結(jié)果婚禮上副瀑,老公的妹妹穿的比我還像新娘。我一直安慰自己恋谭,他們只是感情好糠睡,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著疚颊,像睡著了一般狈孔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上材义,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天除抛,我揣著相機(jī)與錄音,去河邊找鬼母截。 笑死,一個(gè)胖子當(dāng)著我的面吹牛橄教,可吹牛的內(nèi)容都是我干的清寇。 我是一名探鬼主播喘漏,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼华烟!你這毒婦竟也來(lái)了翩迈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤盔夜,失蹤者是張志新(化名)和其女友劉穎负饲,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體喂链,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡返十,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了椭微。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片洞坑。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蝇率,靈堂內(nèi)的尸體忽然破棺而出迟杂,到底是詐尸還是另有隱情,我是刑警寧澤本慕,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布排拷,位于F島的核電站,受9級(jí)特大地震影響锅尘,放射性物質(zhì)發(fā)生泄漏监氢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一鉴象、第九天 我趴在偏房一處隱蔽的房頂上張望忙菠。 院中可真熱鬧,春花似錦纺弊、人聲如沸牛欢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)傍睹。三九已至,卻和暖如春犹菱,著一層夾襖步出監(jiān)牢的瞬間拾稳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工腊脱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留访得,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像悍抑,于是被迫代替她去往敵國(guó)和親鳄炉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容