Toll-Free Bridged
- __bridge 改變指針的索引斋射,在Objective-C和Core Foundation之間,但不改變所有權(quán)
- __bridge_retained或者CFBridgingRetain將Objective-C指針類型轉(zhuǎn)變?yōu)镃ore Foundation指針類型房揭,并且改變所有權(quán),必須調(diào)用CFRelease來(lái)釋放
- __bridge_transfer或者CFBridgingRelease將一個(gè)非non-Objective-C指針轉(zhuǎn)變?yōu)镺bjective-C指針類型吟孙,并且改變所有權(quán)讨阻,啟用ARC芥永,即不需要自己去Release。
內(nèi)存管理
所有權(quán)原則
基本規(guī)則
- 如果創(chuàng)建一個(gè)對(duì)象(亦或是從別的對(duì)象復(fù)制而得)钝吮,將持有這個(gè)對(duì)象
- 如果只是去引用這個(gè)對(duì)象埋涧,不會(huì)有所有權(quán),如果為了避免這個(gè)對(duì)象被釋放奇瘦,可以通過(guò)(CFRetain)去添加引用計(jì)數(shù)棘催。
- 對(duì)于對(duì)象持有者,當(dāng)對(duì)象不再使用的時(shí)候釋放它(CFRelease)
創(chuàng)建規(guī)則
創(chuàng)建方法名中包含"Create"耳标,創(chuàng)建時(shí)持有對(duì)象
-
創(chuàng)建方法名中包含"Copy"醇坝,拷貝時(shí)持有對(duì)象
CFTimeZoneRef CFTimeZoneCreateWithTimeIntervalFromGMT (CFAllocatorRef allocator, CFTimeInterval ti); CFDictionaryRef CFTimeZoneCopyAbbreviationDictionary (void); CFBundleRef CFBundleCreate (CFAllocatorRef allocator, CFURLRef bundleURL); CF_EXPORT CFBagRef CFBagCreate(CFAllocatorRef allocator, const void **values, CFIndex numValues, const CFBagCallBacks *callBacks); CF_EXPORT CFMutableBagRef CFBagCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFBagRef bag);
Get Rule
如果是通過(guò)get方法獲得的對(duì)象,將不持有這個(gè)對(duì)象次坡,必須通過(guò)CFRetain去持有呼猪,但使用結(jié)束的時(shí)候也應(yīng)該去CFRelease,不然會(huì)造成內(nèi)存泄露
CFStringRef CFAttributedStringGetString (CFAttributedStringRef aStr);
實(shí)例變量和參數(shù)傳遞
當(dāng)一個(gè)對(duì)象作為參數(shù)傳遞的時(shí)候砸琅,接收者并沒(méi)有持有這個(gè)對(duì)象宋距,對(duì)象有可能在任意時(shí)刻被釋放掉,從而導(dǎo)致接收者出錯(cuò)症脂,因此接收者需要對(duì)這個(gè)可能被釋放的對(duì)象CFRetain谚赎。當(dāng)接收者使用完畢后淫僻,再去釋放它。
生命周期
Core Foundation的生命周期取決于它自身的引用計(jì)數(shù)壶唤,當(dāng)被創(chuàng)建或者復(fù)制的時(shí)候嘁傀,新的對(duì)象的引用計(jì)數(shù)為1,CFRetain引用計(jì)數(shù)加1视粮,CFRelease引用計(jì)數(shù)減1细办,當(dāng)引用計(jì)數(shù)為0的時(shí)候,該對(duì)象將被釋放掉蕾殴。
/* myString is a CFStringRef received from elsewhere */
myString = (CFStringRef)CFRetain(myString);
CFRelease(myString);
CFIndex count = CFGetRetainCount(myString);//獲取引用計(jì)數(shù)
復(fù)制
在Core Foundation中笑撞,對(duì)象之間利用等號(hào)來(lái)進(jìn)行賦值是不進(jìn)行復(fù)制的,只是復(fù)制了引用钓觉,并沒(méi)有真正持有該對(duì)象茴肥。例如myCFString2 = myCFString1。如果是對(duì)不可變的對(duì)象荡灾,這種賦值會(huì)比較方便簡(jiǎn)潔瓤狐,但是如果是可變對(duì)象,這種賦值方式就很危險(xiǎn)了批幌,因?yàn)樽兞侩S時(shí)會(huì)改變础锐,造成想要獲取的結(jié)果與預(yù)計(jì)不和。
淺復(fù)制
在復(fù)制復(fù)合對(duì)象的時(shí)候荧缘,類似集合對(duì)象CFArray皆警、CFSet.如果只是單純的用等號(hào)來(lái)復(fù)制,復(fù)制的只是引用(如上所述)截粗。如果通過(guò)淺復(fù)制信姓,那么新的集合對(duì)象將被創(chuàng)建,但是集合里面的數(shù)據(jù)并沒(méi)有被復(fù)制绸罗,而只是增加了引用而已意推。
深復(fù)制
如果想要?jiǎng)?chuàng)建一個(gè)完全全新的復(fù)合對(duì)象,那么就必須使用深復(fù)制珊蟀。深復(fù)制比淺復(fù)制多的就是將集合里面的所有對(duì)象也都會(huì)復(fù)制一份菊值。
CFPropertyListRef CFPropertyListCreateDeepCopy ( CFAllocatorRef allocator, CFPropertyListRef propertyList, CFOptionFlags mutabilityOption );
在構(gòu)造函數(shù)中使用Allocators
每個(gè)Core Foundation不透明類型都有一個(gè)或多個(gè)構(gòu)造方法。所有的構(gòu)造函數(shù)的第一個(gè)傳入?yún)?shù)都是 allocator object(CFAllocatorRef類型)系洛。一些函數(shù)也會(huì)有allocator參數(shù)來(lái)進(jìn)行分配和銷毀俊性。
如何獲取一個(gè)allocator:
- 利用常量 kCFAllocatorSystemDefault,定義一個(gè)默認(rèn)的allocator描扯。
- NULL或者kCFAllocatorDefault定页,定義常用的allocator,或者是默認(rèn)的allocator绽诚。
- 設(shè)置為常量 kCFAllocatorNull典徊,說(shuō)明allocator并沒(méi)有被分配
- 也可以通過(guò)CFGetAllocator從別的對(duì)象獲取
使用Allocator Context
每個(gè)分配器都會(huì)有一個(gè)Core Foundation的context杭煎。context是由函數(shù)指針構(gòu)成,定義了對(duì)象的操作環(huán)境卒落。
定義如下:
typedef struct {
CFIndex version;
void * info;
const void *(*retain)(const void *info);
void (*release)(const void *info);
CFStringRef (*copyDescription)(const void *info);
void * (*allocate)(CFIndex size, CFOptionFlags hint, void *info);
void * (*reallocate)(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info);
void (*deallocate)(void *ptr, void *info);
CFIndex (*preferredSize)(CFIndex size, CFOptionFlags hint, void *info);
} CFAllocatorContext;
如果有一些用戶自定義的數(shù)據(jù)羡铲,可以通過(guò)CFAllocatorGetContext函數(shù)來(lái)獲取CFAllocatorContext的內(nèi)容
static int numOutstandingAllocations(CFAllocatorRef alloc) {
CFAllocatorContext context;
context.version = 0;
CFAllocatorGetContext(alloc, &context);
return (*(int *)(context.info));
}
對(duì)于Allocator理解還不夠,只是單純看了官方文檔儡毕,有機(jī)會(huì)再深入研究一下也切。