版本記錄
版本號(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)。
Date
和number
類型抽象時(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ì)象模型留瞳。
- Opaque Types
- Object References
- Polymorphic Functions
- Varieties of Objects
- Comparing Objects
- Inspecting Objects
此外,還有其他非對(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)定義俐填。
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ù)。
-
CFType
提供了幾個(gè)用于操作和獲取對(duì)象引用計(jì)數(shù)的多態(tài)函數(shù)导俘。有關(guān)這些功能的更多信息峦耘,請(qǐng)參閱Memory Management Programming Guide for Core Foundation。
-
-
比較對(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铺敌。
- CFType為您提供檢查對(duì)象的方法,從而了解其內(nèi)容及其所屬類型烘跺。
您還可以通過(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
蝎宇、Copy
和Create
之間有一個(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ù)值诸典,特別是CFIndex
和CFTypeID
描函,可隨著處理器的地址大小的增長(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):CFCopyDescription
和CFCopyTypeIDDescription
函數(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中,由UIColor
的CGColor
方法返回的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_retained
或CFBridgingRetain
將一個(gè)Objective-C指針轉(zhuǎn)換為Core Foundation指針,并將所有權(quán)轉(zhuǎn)讓給您闸氮。您負(fù)責(zé)調(diào)用CFRelease
或相關(guān)函數(shù)以放棄該對(duì)象的所有權(quán)剪况。 -
__bridge_transfer
或CFBridgingRelease
將非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版本堪唐。
后記
未完,待續(xù)~~~