Objective-C 和 Core Foundation 對象相互轉(zhuǎn)換的內(nèi)存管理總結(jié)

iOS允許Objective-C 和 Core Foundation 對象之間可以輕松的轉(zhuǎn)換慢宗,拿 NSString 和 CFStringRef 來說昧谊,直接轉(zhuǎn)換豪無壓力:

CFStringRef aCFString = (CFStringRef)aNSString;

NSString *aNSString = (NSString *)aCFString;

針對內(nèi)存管理問題每币,ARC 可以幫忙管理 Objective-C 對象, 但是不支持 Core Foundation 對象的管理力麸,所以轉(zhuǎn)換后要注意一個問題:誰來釋放使用后的對象拐辽。 本文重點(diǎn)總結(jié)一下類型轉(zhuǎn)換后的內(nèi)存管理磁滚。

一佛吓、非ARC的內(nèi)存管理

倘若不使用ARC,手動管理內(nèi)存垂攘,思路比較清晰维雇,使用完,release轉(zhuǎn)換后的對象即可晒他。

//NSString 轉(zhuǎn) CFStringRef

CFStringRef aCFString = (CFStringRef) [[NSString alloc] initWithFormat:@"%@", string];

//...

CFRelease(aCFString);

//CFStringRef 轉(zhuǎn) NSString

CFStringRef aCFString = CFStringCreateWithCString(kCFAllocatorDefault,

bytes,

NSUTF8StringEncoding);

NSString *aNSString = (NSString *)aCFString;

//...

[aNSString release];

二吱型、ARC下的內(nèi)存管理

ARC的誕生大大簡化了我們針對內(nèi)存管理的開發(fā)工作,但是只支持管理 Objective-C 對象, 不支持 Core Foundation 對象陨仅。Core Foundation 對象必須使用CFRetain和CFRelease來進(jìn)行內(nèi)存管理津滞。那么當(dāng)使用Objective-C 和 Core Foundation 對象相互轉(zhuǎn)換的時候,必須讓編譯器知道灼伤,到底由誰來負(fù)責(zé)釋放對象触徐,是否交給ARC處理。只有正確的處理狐赡,才能避免內(nèi)存泄漏和double free導(dǎo)致程序崩潰锌介。

根據(jù)不同需求,有3種轉(zhuǎn)換方式

__bridge ? ? ? ? ? ? ? ? ? ? ? ?(不改變對象所有權(quán))

__bridge_retained 或者 CFBridgingRetain() ? ? ? ? ? ? ? (解除 ARC 所有權(quán))

__bridge_transfer 或者 CFBridgingRelease() ? ? ? ? ? ? (給予 ARC 所有權(quán))

1. __bridge_retained 或者 CFBridgingRetain()

__bridge_retained 或者 CFBridgingRetain() ?將Objective-C對象轉(zhuǎn)換為Core Foundation對象猾警,把對象所有權(quán)橋接給Core Foundation對象孔祸,同時剝奪ARC的管理權(quán),后續(xù)需要開發(fā)者使用CFRelease或者相關(guān)方法手動來釋放對象发皿。

來看個例子:

- (void)viewDidLoad

{

[super viewDidLoad];

NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];

CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;

(void)aCFString;

//正確的做法應(yīng)該執(zhí)行CFRelease

//CFRelease(aCFString);

}

程序沒有執(zhí)行CFRelease崔慧,造成內(nèi)存泄漏:

CFBridgingRetain() ?是 __bridge_retained 的宏方法,下面兩行代碼等價:

CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;

CFStringRef aCFString = (CFStringRef) CFBridgingRetain(aNSString);

2. __bridge_transfer 或者 CFBridgingRelease()

__bridge_transfer 或者 CFBridgingRelease() ?將非Objective-C對象轉(zhuǎn)換為Objective-C對象穴墅,同時將對象的管理權(quán)交給ARC惶室,開發(fā)者無需手動管理內(nèi)存。

接著上面那個內(nèi)存泄漏的例子玄货,再轉(zhuǎn)成OC對象交給ARC來管理內(nèi)存皇钞,無需手動管理,也不會出現(xiàn)內(nèi)存泄漏:

- (void)viewDidLoad

{

[super viewDidLoad];

NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];

CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;

aNSString = (__bridge_transfer NSString *)aCFString;

}

CFBridgingRelease() 是__bridge_transfer的宏方法松捉,下面兩行代碼等價:

aNSString = (__bridge_transfer NSString *)aCFString;

aNSString = (NSString *)CFBridgingRelease(aCFString);

3. __bridge

__bridge 只做類型轉(zhuǎn)換夹界,不改變對象所有權(quán),是我們最常用的轉(zhuǎn)換符隘世。

從OC轉(zhuǎn)CF可柿,ARC管理內(nèi)存:

- (void)viewDidLoad

{

[super viewDidLoad];

NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];

CFStringRef aCFString = (__bridge CFStringRef)aNSString;

(void)aCFString;

}

從CF轉(zhuǎn)OC鸠踪,需要開發(fā)者手動釋放,不歸ARC管:

- (void)viewDidLoad

{

[super viewDidLoad];

CFStringRef aCFString = CFStringCreateWithCString(NULL, "test", kCFStringEncodingASCII);

NSString *aNSString = (__bridge NSString *)aCFString;

(void)aNSString;

CFRelease(aCFString);

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末复斥,一起剝皮案震驚了整個濱河市营密,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌目锭,老刑警劉巖评汰,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異痢虹,居然都是意外死亡被去,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門世分,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缀辩,你說我怎么就攤上這事臭埋。” “怎么了臀玄?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵瓢阴,是天一觀的道長。 經(jīng)常有香客問我健无,道長荣恐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任累贤,我火速辦了婚禮叠穆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘臼膏。我一直安慰自己硼被,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布渗磅。 她就那樣靜靜地躺著嚷硫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪始鱼。 梳的紋絲不亂的頭發(fā)上仔掸,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天,我揣著相機(jī)與錄音医清,去河邊找鬼起暮。 笑死,一個胖子當(dāng)著我的面吹牛会烙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼氓英,長吁一口氣:“原來是場噩夢啊……” “哼卵慰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起毫玖,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后村斟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡抛猫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年蟆盹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闺金。...
    茶點(diǎn)故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡逾滥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出败匹,到底是詐尸還是另有隱情寨昙,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布掀亩,位于F島的核電站舔哪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏槽棍。R本人自食惡果不足惜捉蚤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望炼七。 院中可真熱鬧缆巧,春花似錦、人聲如沸豌拙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽姆蘸。三九已至墩莫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間逞敷,已是汗流浹背狂秦。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留推捐,地道東北人裂问。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親堪簿。 傳聞我的和親對象是個殘疾皇子痊乾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評論 2 355

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