[譯]iOS Core Foundation Design Concepts

本文翻譯: Core Foundation design concept

簡介

Core Foundation 是一組慨念源自O(shè)C基礎(chǔ)框架的編程接口,并使用c語言實(shí)現(xiàn)的庫.為了實(shí)現(xiàn)這個庫,Core Foundation用C語言實(shí)現(xiàn)一個限制對象模型.Core Foundation定義不透明類型來封裝數(shù)據(jù)和函數(shù),之后就稱他們?yōu)?對象".
Core Foundation對象設(shè)計的編程接口具有易用性和可復(fù)用性.在普通層次下,Core Foundation有以下特性:

  • 能夠在繁雜多樣的框架和庫中共享數(shù)據(jù)和代碼
  • 使得在一定程度上獨(dú)立于操作系統(tǒng)成為可能
  • 支持使用unicode字符串的國際化
  • 提供一些API和其他有用的功能,包括一個插件架構(gòu),XML屬性列表等

Core Foundation使OS X上不同的框架和庫共享代碼與數(shù)據(jù)成為可能.應(yīng)用,庫,框架讓你在平常C編程中,定義混合Core Foundation類型的接口;因此,它們可以計算數(shù)據(jù)--就像Core Foundation對象--通過這些接口設(shè)計算各自的數(shù)據(jù).
Core Foundation在已確定的服務(wù)和Cocoa的Foundation框架之間提供"toll-free bridging"(無代價橋接). toll-free bridging能將函數(shù)參數(shù)中的Core Foundation對象替換成Cocoa對象或者反過來.
一些Core Foundation類型和函數(shù)是在不同操作系統(tǒng)上特定代碼實(shí)現(xiàn)的抽象. 使用這些API能更容易適配不同平臺.
date與number類型抽象了時間工具,并提供絕對時間和公歷時間的之間的轉(zhuǎn)換工具.它還抽象了數(shù)字值,并為這些內(nèi)部表示不同的值提供的互轉(zhuǎn)工具.
Core Foundation給應(yīng)用開發(fā)帶來其中一個主要的好處是支持國際化.通過框架中的字符串對象,Core Foundation使國際化在OS X與Cocoa上接口的編寫與實(shí)現(xiàn)變得更簡單,健壯和一致.這個特性的本質(zhì)部分是一種類型--CFString, 代表一個16bit的Unicode字符數(shù)組. CFString對象能靈活地支持百萬字節(jié)的字符, 且使用一些足夠簡單的低層的接口就能計算字符數(shù)據(jù).它達(dá)到了跟與之關(guān)聯(lián)的標(biāo)準(zhǔn)C字符串差不多的性能.
你應(yīng)該閱讀這個文檔來了解Core Foundation之下的基本設(shè)計原則和Core Foundation對象跟Cocoa(Touch)對象之間的交互.

不透明類型

Core Foundation對象模型基于不透明類型,且支持封裝和多態(tài)函數(shù).
基于不透明類型的對象的各個字段隱藏于客戶端,但是這些類型的函數(shù)能提供大多數(shù)字段值.Figure 1 描繪了不透明類型所隱藏的數(shù)據(jù)且僅展示其接口給客戶端.

Note: "Class"不是用來指向不透明類型的,盡管類和不透明類型概念上相似,可很多人可能被這個詞混淆.然而,Core Foundation文檔所指的類型是特定的,這些類型的數(shù)據(jù)承載實(shí)例就稱之為"對象"

Core Foundation有很多不透明類型,而且它們的名字說明了它們的預(yù)期用途.例如,CFString 是一個用來"展示"和操作Unicode字符數(shù)組的不透明類型(CF是Code Foundation的前綴). CFArray是基于下標(biāo)的泛型集合.一個不透明類型支持的函數(shù),常量和其他次要的數(shù)據(jù)類型通常定義在其類型對應(yīng)名字的頭文件中.例如CFArray.h,CFArray包含定義符號.

Figure 1  An opaque type
Figure 1 An opaque type

不透明類型的優(yōu)點(diǎn)

部分情況下,一個不透明類型似乎要通過令人沮喪的結(jié)構(gòu)內(nèi)容直接存取來增加一些沒有必要的限制. 此外,似乎不透明的類型可能會影響項目性能相關(guān)的開銷.但是不透明類型的好處要大于這些表面的局限性.
不透明類型為底層功能的實(shí)現(xiàn)提供更好的靈活性和抽象性.通過隱藏結(jié)構(gòu)字段的詳細(xì)信息,Core Foundation減少發(fā)在客戶端(Xcode)編碼時,字段詳情被更改后代碼出錯的幾率.此外,如果暴露不透明類型并允許優(yōu)化,可能會造成困惑(譯注: 其他人可能看不懂其優(yōu)化代碼,還不如封裝起來).例如CFString "正式"代表UniChar的16bit字符數(shù)組.然而, CFString可能選擇儲存一個ASCII范圍內(nèi)8bit數(shù)值的字符串.復(fù)制一個不可變的對象可能(經(jīng)常發(fā)生)導(dǎo)致共同引用一個對象而不是內(nèi)存中兩個獨(dú)立的對象.(查看Core Foundation內(nèi)存管理編程指南).
繼續(xù)CFString這個例子,使用一個不透明類型來儲存字符似乎太笨重.事實(shí)證明,并不是這樣的,CPU消耗的資源比使用簡單的C字符數(shù)組高不了多少,況且經(jīng)常比他們低.另外,不透明并不一定說明這一個不透明類型從不提供直接訪問內(nèi)容的機(jī)制.CFString,對于它的實(shí)例,提供了CFStringGetCStringPtr函數(shù)來直接訪問.
最后,你可以在一定的程度上自定義一些不透明類型.例如,集合類型允許為集合的每一個成員上為喚醒函數(shù)定義一個回調(diào).集合類型允許調(diào)用函數(shù)時定義一個回調(diào)(譯注:callback,可以理解為函數(shù)指針),并讓每個集合成員調(diào)用.

對象引用

你可以通過引用來指向一個Core Foundation對象(不透明類型).對于頭文件的中的每一個不透明類型,你將會注意到一行或兩行相似的,類似下面的語句:

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

聲明這些指針指向(私有的)不可變和可變版本的結(jié)構(gòu).Core Foundation中許多函數(shù)的參數(shù)和返回值采用對象引用類型,而且從不使用typedef私有結(jié)構(gòu)的類型. 例如:

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

查看 對象的種類獲取更多信息,可變的的還有其他種類的不透明對象.
每一個Core Foundation不透明類型給他們的對象定義一個唯一類型ID,如在CFArray對象上的CFArrayRef.類型ID是類型為CFTypeID的整型,這個ID標(biāo)識了一個Core Foundation所屬的不透明類型.在各種上下文中使用類型ID, 如在你操作各式各樣的容器時使用.Core Foundation提供一些編程性接口,用于獲取和計算類型ID的值.

重要:由于類型ID的值可以隨著版本的變化而變化,你的類型ID應(yīng)該不能依賴已保存的或?qū)懰赖念愋虸D,也不應(yīng)該被任何能觀察到的屬性賦值(例如賦給它一個簡單的整形:23333).

另外,Core Foundation定義了一個通用的對象引用(object-reference)類型, CFTypeRef,類似其他面向?qū)ο笳Z言的基(root)類.這個通用的引用作為一個多態(tài)函數(shù)的參數(shù)與返回值的占位符類型,可以指向任何Core Foundation對象.查看多態(tài)函數(shù)獲取更多關(guān)于這個課題的信息.查看Core Foundation的內(nèi)存管理指南討論使用對象引用時內(nèi)存管理的相關(guān)問題.

多態(tài)函數(shù)

Core Foundation提供一些多態(tài)函數(shù),這些函數(shù)可以將任意Core Foundation對象作為參數(shù)和(有一個例子:CFRetain)可以返回任意Core Foundation對象.這些參數(shù)和返回值的類型是CFTypeRef,是一個通用的對象引用(object-reference)類型.CFType是類似于其他面向?qū)ο笳Z言中的根類,因?yàn)樗暮瘮?shù)可以被其他所有對象復(fù)用.
你可以使用多態(tài)函數(shù)對所有的Core Foundation對象進(jìn)行一些通用操作:

  • 引用計數(shù)
    CFType提供幾個多態(tài)函數(shù)來計算和獲取對象的引用計數(shù).查看Core Foundation的內(nèi)存管理指南獲取更多的關(guān)于這些函數(shù)的信息.
  • 比較對象
    CFEqual函數(shù)能比較任何兩個Core Foundation對象(查看比較對象).等式成立的基本條件取決于同類型對象的比較.例如,如果比較兩個CFString對象,該測試涉及逐個字符的比較.
  • 哈希對象
    CFHash函數(shù)返回一個唯一的能夠標(biāo)識Core Foundation對象的哈希碼(查看比較對象).你可以把哈希碼當(dāng)哈希表數(shù)據(jù)結(jié)構(gòu)中的表地址.如果兩個對象相等(由CFEqual函數(shù)決定),他們必須有相同的哈希值.
  • 核查對象
    CFType提供核查對象的函數(shù),從而了解它們的內(nèi)容以及他們"所屬"的類型.CFCopyDescription函數(shù)返回一個描述該對象的字符串(更切確地說,是一個CFString對象的引用).CFCopyTypeIDDescription函數(shù)需要提供一個CFTypeID參數(shù)而不是CFTypeRef.這個函數(shù)返回一個描述標(biāo)識一個不透明類型的類型ID的字符串引用.這些函數(shù)主要用來協(xié)助調(diào)試.查看核查對象獲取更多相關(guān)的函數(shù).
    你還可以通過CFGetTypeID函數(shù)獲得不透明對象的類型ID,通過這個ID決定一個通用類型對象所屬的不透明類型,再將已知類型ID對應(yīng)的值相比較.查看檢查對象獲取更多關(guān)于這個任務(wù)的信息.

對象的種類

不透明類型擁有多達(dá)3種基本種類,或者"口味".(譯注:這里為了跟之前的對象類型(object type)區(qū)分,故意使用種類或'口味').基于可擴(kuò)展性和可編輯性的特點(diǎn)分為以下:

  • 不可變和固定大小
  • 可變和固定大小
  • 可變和不固定大小

可變對象是可編輯的,意味著他們的內(nèi)容可以修改.不可變對象不能編輯的;一旦創(chuàng)建之后就無法再改變.對不可變對象的任何修改都會導(dǎo)致一些(譯注:編譯器)錯誤.一個固定大小的可變對象有一個最大值來限制其大小的增長;就CFString來說,一個CFString可能是字符串中的字符個數(shù),對于一個容器來說,其限制可能是元素的數(shù)量.
一些不透明類型,例如CFStringCFArray,可以創(chuàng)建所有三種口味的對象.大部分不透明類型可以創(chuàng)建不可變的,固定大小的對象,至少有一個無限制的創(chuàng)建函數(shù)來創(chuàng)建無限制對象(如CFArrayCreate).決定可變對象的可變大小或不可變大小的是CreateMutable函數(shù)的容量(capacity)參數(shù)和長度最大值(maximum-length)參數(shù);任何正整數(shù)都能生成對固定大小的對象,但是參數(shù)為0則生成一個可變大小對象.
使用帶有"Mutable"名字的類型指向可變對象,例如,CFMutableStringRef.

命名約定

Core Foundation中主要編程接口的約定是使用不透明類型的名字中最密切相關(guān)的符號作為符號的前綴.對于函數(shù),這個前綴不僅標(biāo)識這該函數(shù)"屬于"那個類型,而且經(jīng)常用來標(biāo)識函數(shù)動作(action)的目標(biāo)(target)對象的類型(type).(有一個例外是那些以k作為前綴的常量).在頭文件中有一些例子:

/* 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;

除上述之外,Core Foundation中有一小部分編程接口約定是有關(guān)于不透明類型和內(nèi)存管理的.

  • Get,Copy和Create之間有著很重大的區(qū)別,在于函數(shù)的返回值的命名.如果你使用Get函數(shù),只是無法確定對象的生命周期.為了確保對象能夠持續(xù)存在,你可以持有(retain)它(使用CFRetain函數(shù)),或者在一些情況下,復(fù)制(copy)一份.如果你使用Copy或Create函數(shù),你必須負(fù)責(zé)釋放對象(使用CFRelease函數(shù)).更多詳情請查看Core Foundation內(nèi)存管理指南

  • 部分Core Foundation對象有它們自己的命名約定,并以此加強(qiáng)通用操作的一致性.例如,集合(collection)將下列動詞嵌入函數(shù)名,已表示集合中的元素的特定操作.

    • Add意味'如果存在就添加,如果存在就不做任何事'(針對某一個集合實(shí)例)
    • Replace意味'如果存在就替換,如果不存在就不做任何事'
    • Set意味'如果不存在就添加,如果存在就替換'
    • Remove意味'如果存在就刪除,如果不存在就不做任何事'
  • CFIndex類型用于下標(biāo)(index),計數(shù)(count),長度(length),和大小(size),并作為函數(shù)的參數(shù)或者返回值.這個類型(整形)的值(當(dāng)前是32位),可以隨著處理器地址大小的增長而增長.在指針大小不同的架構(gòu)上,如果是64位處理器,CFIndex可能是64位,這取決于int的大小.在Core Foundation參數(shù)中使用相同類型CFIndex的變量進(jìn)行交互,可以確保您的代碼有更高的源碼兼容性.

  • 一些Core Foundation頭文件似乎定義不透明類型,但實(shí)際上卻包含便利函數(shù)而不是關(guān)聯(lián)一些特定的類型.恰當(dāng)?shù)睦邮?code>CFPropertyList.h.CFPropertyList是下列屬性列表類型中任意一個類型的占位符類型:CFString,CFDate,CFBoolean,CFNumber,CFDate,CFArrayCFDictionary.

  • 除非特殊說明,否則所有傳遞引用參數(shù)并打算返回值都可以接受NULL.這表明調(diào)用者不需要關(guān)心函數(shù)的返回值.

其他類型

Core Foundation定義若干個數(shù)據(jù)類型,并在函數(shù)中使用.這些類型存在的目的是抽象原始值.這個原始值可能隨處理器地址空間改變而改變.例如CFIndex類型,應(yīng)用于下標(biāo)(index), 計數(shù)(count),長度(length),和大小(size)參數(shù).CFOptionFlags類則用于位字段參數(shù),CFHashCode類型包含從CFHash函數(shù)和已確定的哈希回調(diào)中返回的哈希結(jié)果.
其他基本類型用于傳入函數(shù)和函數(shù)返回的比較值與范圍值.CFRange是一個指定線性隊列的任意一部分的結(jié)構(gòu),從字符串中的數(shù)組到集合中的元素.對于比較函數(shù),CFComparisonResult類型定義枚舉常量來代表適當(dāng)?shù)姆祷刂?等于,小于,大于).部分Core Foundation函數(shù)傳入一個回調(diào)到比較函數(shù)中去;如果你需要自定義比較操作,函數(shù)必須符合CFComparatorFunction中指定的類型(譯注:函數(shù)的參數(shù)必須與(const void *val1, const void *val2, void *context)相同).

重要: 只要其值是整形值,那么其類型一定是Core Foundation類型,特別是CFIndexCFTypeID,可以隨著處理器尋址大小的增長而增長.在Core Foundation參數(shù)中使用相同類型CFIndex的變量進(jìn)行交互,可以讓確保您的代碼有更高的源碼兼容性.

Core Foundation中體統(tǒng)的其他不透明類型在其他主題中討論.

比較對象

你可用CFEqual函數(shù)來比較兩個Core Foundation對象.如果兩個對象在本質(zhì)上是相等的,函數(shù)將返回一個boolean類型的true值."本質(zhì)上"相等取決于相同類型的對象的比較.當(dāng)你比較兩個CFString對象,不管他們的編碼和是否可變,當(dāng)他們逐個字符完全匹配時, Core Foundation則認(rèn)為他們本質(zhì)上相等.兩個CFArray對象比較,當(dāng)它們有相同數(shù)量的元素和數(shù)組中每一個元素對象與對應(yīng)數(shù)組中的元素本質(zhì)上相等,這時會認(rèn)為他們本質(zhì)上相等.很明顯,比較對象必須是相同類型(不管可變或不可變)才會認(rèn)為是相等的.
下面代碼片段給你展示了可能使用CFEqual函數(shù)比較一個常量與傳入?yún)?shù)是否相等.
Listing 1 比較Core Foundation對象

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

核查對象

Core Foundation對象的主要特征是它們都基于一個不透明(或私有)類型;可能因此難以直接核查對象的內(nèi)部數(shù)據(jù).然而,基礎(chǔ)服務(wù)提供了兩個函數(shù)來檢查Core Foundation對象.這些函數(shù)返回對象及對象類型的描述信息.
為了找出Core Foundation對象的內(nèi)容,調(diào)用CFCopyDescription函數(shù)并傳進(jìn)其對象.然后打印所引用的字符串對象所"包含"的字符序列.

Listing 1 使用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);
  }

這個例子顯示了一種打印描述信息(description)的途徑.你不應(yīng)該使用CFStringGetBytes,而是使用CFString函數(shù)來獲取真正的字符串.
為了確定一個"未知"對象的類型,用CFGetTypeID函數(shù)取得它的類型ID,將值與已知的類型ID進(jìn)行比較,直到匹配.可以使用CFGetTypeID獲取一個對象的類型ID.每一個不透明類型還定義了一個CFTypeGetTypeID表格的函數(shù)(例如CFArrayGetTypeID);這個函數(shù)返回給定類型的類型ID.在此之前,你可以測試一下一個CFType對象是否是指定不透明類型的成員.

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

為了打印Core Foundation對象的類型在調(diào)試狀態(tài)下的相關(guān)信息.使用CFGetTypeID函數(shù)來獲取這個類型ID,然后通過這個值傳入CFCopyTypeIDDescription函數(shù):

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

注意: 字符串基礎(chǔ)功能中包含兩個函數(shù):CFShowCFShowStr,都聲明在CFString.h頭文件中.在調(diào)試模式下,你可以調(diào)用它們打印Core Foundation的描述.

重要: CFCopyDescriptionCFCopyTypeIDDescription只在調(diào)試模式下使用.不要創(chuàng)建任何依賴它們的代碼,因?yàn)槊枋鲂畔⑴c他們的格式隨時改變.

無代價橋接類型

在Core Foundation框架與Foundation框架中有若干可相互轉(zhuǎn)換的數(shù)據(jù)類型.可相互裝換的數(shù)據(jù)類型也被稱為無代價橋接(toll-free bridged)數(shù)據(jù)類型.這意味著你可以使用相同的數(shù)據(jù)結(jié)構(gòu)作為參數(shù)傳進(jìn)Core Foundation調(diào)用的函數(shù)和作為一個Objective-C消息發(fā)送的接收器.例如,NSLocale(查看NSLocale Class Reference), 與之對應(yīng)的Core Foundation的CFLocal(查看CFLocale)是可相互轉(zhuǎn)換的.
不是所有的數(shù)據(jù)類型都是無代價橋接的,甚至通過他們的名字可能猜得出他們是有代價橋接的.例如NSRunLoop轉(zhuǎn)換到CFRunLoop不是無代價橋接,NSBundle轉(zhuǎn)換至CFBundle不是無代價橋接.NSDateFormate轉(zhuǎn)換到CFDateFormatter也不是.table 1提供了一張?zhí)峁┑臒o條件橋接的表.

注意: 在你使用corefoundation的集合時,如果安裝(install)一個自定義回調(diào)(call back),包括NULL回調(diào).從Objective-C訪問時,該自定義回調(diào)的內(nèi)存管理的行為是沒有定義的.

強(qiáng)制類型轉(zhuǎn)換和對象生命期的語義(Casting and Object Lifetime Semantics)

通過無條件橋接,當(dāng)你在一個方法中,看到有些參數(shù),例如NSLocale *參數(shù),可以傳進(jìn)一個CFLocaleRef;在函數(shù)看到CFLocaleRef參數(shù),你可以傳一個NSLocale實(shí)例.不過你必須為編譯器提供其他信息: 首先, 將一個類型強(qiáng)制轉(zhuǎn)換(cast)為其他類型;另外,你可能還要指示出對象的聲明期語義.
編譯器理解Objective-C方法返回的Core Foundation類型和遵循過去Cocoa命名約定(查看高級內(nèi)存管理編程指南).例如,編譯器知道在iOS中,通過UIColor本身并沒有CGColor方法來返回一個CGColor. 你必須使用適當(dāng)?shù)膹?qiáng)制類型轉(zhuǎn)換(cast),就像下面所展示的:

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

編譯器不會自動管理Core Foundation對象的生命期.選擇強(qiáng)制類型轉(zhuǎn)換(cast)(在objc/runtime.h中定義)和Core Foundation風(fēng)格的宏(在NSObject.h中定義)其中一個,告訴編譯器關(guān)于對象的持有者.

  • __bridge將一個指向Objective-C與Core Foundation兩者之一的指針相互轉(zhuǎn)換,沒有轉(zhuǎn)換持有權(quán).

  • __bridge_retainedCFBridgingRetain強(qiáng)制類型轉(zhuǎn)換(cast)指向Objective-C的指針為Core Foundation指針并把持有權(quán)轉(zhuǎn)給你.
    你負(fù)責(zé)調(diào)用CFRelease或相關(guān)函數(shù)來放棄對象的持有權(quán).

  • __bridge_transferCFBridgingRelease移動一個非Objective-C指針到Objective-C,并且將對象持有權(quán)交給ARC.
    ARC 有負(fù)責(zé)放棄對象的持有權(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]);
    

下一個例子展示Core Foundation內(nèi)存管理函數(shù)的用法.這些函數(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.
}

無代價橋接類型

table 1 提供一個可在Core Foundation和Foundation之間相互裝換的數(shù)據(jù)類型的列表.對于每一對,表中來列舉了它們之間無代價橋接變得有效時OS X的版本.
Table 1 在Core Foundation和Foundation之間相互裝換的數(shù)據(jù)類型

Core Foundation type Foundation Class Availability
CFArrayRef NSArray OS X v10.0
CFAttributedStringRef NSAttributedString OS X v10.4
CFCalendarRef NSCalendar OS X v10.4
CFCharacterSetRef NSCharacterSet OS X v10.0
CFDataRef NSData OS X v10.0
CFDateRef NSDate OS X v10.0
CFDictionaryRef NSDictionary OS X v10.5
CFErrorRef NSError OS X v10.5
NSLocale NSLocale OS X v10.4
CFMutableArrayRef NSMutableArray OS X v10.0
CFMutableAttributedStringRef NSMutableAttributedString OS X v10.4
CFMutableCharacterSetRef NSMutableCharacterSet OS X v10.0
CFMutableDataRef NSMutableData OS X v10.0
CFMutableDictionaryRef NSMutableDictionary OS X v10.0
CFMutableSetRef NSMutableSet OS X v10.0
CFMutableStringRef NSMutableString OS X v10.0
CFNumberRef NSNumber OS X v10.0
CFReadStreamRef NSInputStream OS X v10.0
CFRunLoopTimerRef NSTimer OS X v10.0
CFSetRef NSSet OS X v10.0
CFStringRef NSString OS X v10.0
CFTimeZoneRef NSTimeZone OS X v10.0
CFURLRef NSURL OS X v10.0
CFWriteStreamRef NSOutputStream OS X v10.0
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 版本記錄 前言 Core Foundation框架(CoreFoundation.framework)是一組C語言...
    刀客傳奇閱讀 3,230評論 0 3
  • *面試心聲:其實(shí)這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,585評論 30 472
  • 序言 目前形勢,參加到iOS隊伍的人是越來越多,甚至已經(jīng)到供過于求了。今年,找過工作人可能會更深刻地體會到今年的就...
    iOS_Alex閱讀 1,657評論 1 24
  • 序言 目前形勢,參加到iOS隊伍的人是越來越多,甚至已經(jīng)到供過于求了。今年,找過工作人可能會更深刻地體會到今年的就...
    麥兜兜買兜兜閱讀 721評論 1 4
  • 第1篇Objective-C準(zhǔn)備篇 第1章Objective-C學(xué)習(xí)環(huán)境準(zhǔn)備 1.1Objective-C基礎(chǔ) 1...
    YHWXQ簡簡單單的生活閱讀 1,085評論 2 2

友情鏈接更多精彩內(nèi)容