iOS 內(nèi)存管理

iOS 無(wú)論是在MRC 還是ARC情況下 OC 都是用引用計(jì)數(shù)來管理內(nèi)存!

內(nèi)存管理的原則是: 誰(shuí)創(chuàng)建 誰(shuí)來釋放 ??誰(shuí)引用,誰(shuí)管理


例如MRC下:

NSObject * a = [NSObject alloc] init]; ? ?a 引用計(jì)數(shù)為 1

NSObject * b; //相同類型局部變量b

b = ?[a retain] ? //b這個(gè)時(shí)候可以使用a ? ? a的引用計(jì)數(shù)+1 ?= ?2

[a realse]; a的引用計(jì)數(shù)為1

[a realse];?a的引用計(jì)數(shù)為0


alloc 、new、 ?copy、 mutableCopy? 引用計(jì)數(shù) = 1 ? ? 生成并持有對(duì)象?

retain ?引用計(jì)數(shù)+1 ?并持有這個(gè)對(duì)象

strong ?引用計(jì)數(shù)+1 ? MRC下會(huì)做一次retain ARC下省略?

addobject 類似的 ?想要持有這個(gè)對(duì)象 ?引用計(jì)數(shù)+1 ?

release 引用計(jì)數(shù) - 1?

dealloc 引用計(jì)數(shù)為0的時(shí)候調(diào)用


ARC管理方法:

在ARC內(nèi)存管理機(jī)制中,id和其他對(duì)象類型變量必須是以下四個(gè)ownership qualifiers其中一個(gè)來修飾:

__strong ? 強(qiáng)引用

__weak ?弱引用?

__unsafe_unretained ??它是不安全的。它跟__weak相似,被它修飾的變量都不持有對(duì)象的所有權(quán),但當(dāng)變量指向的對(duì)象的RC為0時(shí),變量并不設(shè)置為nil,而是繼續(xù)保存對(duì)象的地址;這樣的話,對(duì)象有可能已經(jīng)釋放,但繼續(xù)訪問,就會(huì)造成非法訪問(Invalid Access)

__autoreleasing

NSAutoreleasePool?*pool?=?[[NSAutoreleasePool?alloc]?init];

//?put?object?into?pool

id?obj?=?[[NSObject?alloc]?init];

[obj?autorelease];

[pool?drain];


/*?超過autorelease?pool作用域范圍時(shí),obj會(huì)自動(dòng)調(diào)用release方法?*/

引入ARC之后,寫法比之前更加簡(jiǎn)潔:

@autoreleasepool?{

????id?__autoreleasing?obj?=?[[NSObject?alloc]?init];

}




ARC需要注意的事項(xiàng)?

1.過度使用?block?之后,無(wú)法解決循環(huán)引用問題


由于Core Foundation 框架并不支持 ARC,此時(shí)編譯器不知道該如何處理這個(gè)同時(shí)有 ObjC 指針和 CFTypeRef 指向的對(duì)象,所以除了轉(zhuǎn)換類型,還需指定內(nèi)存管理所有權(quán)的改變,可通過 __bridge、__bridge_retained 和 CFBridgingRetain、__bridge_transfer 和 CFBridgingRelease。


2.遇到底層?Core Foundation?對(duì)象,需要自己手工管理它們的引用計(jì)數(shù)時(shí),我們需轉(zhuǎn)換關(guān)鍵字,作為橋接轉(zhuǎn)換以解決 Core Foundation 對(duì)象與 Objective-C 對(duì)象相對(duì)轉(zhuǎn)換的問題:

__bridge:使用__bridge標(biāo)記可以在不修改相關(guān)對(duì)象的引用計(jì)數(shù)的情況下,將對(duì)象從Core Foundation框架數(shù)據(jù)類型轉(zhuǎn)換為Foundation框架數(shù)據(jù)類型(反之亦然)。

CF和OC對(duì)象轉(zhuǎn)化時(shí)只涉及對(duì)象類型不涉及對(duì)象所有權(quán)的轉(zhuǎn)化

只是聲明類型轉(zhuǎn)變,但是不做內(nèi)存管理規(guī)則的轉(zhuǎn)變

CFStringRef?s1?=?(__bridge?CFStringRef)?[[NSString?alloc]?initWithFormat:@"Hello,?%@!",?name];

只是做了 NSString 到 CFStringRef 的轉(zhuǎn)化,但管理規(guī)則未變,依然要用 Objective-C 類型的 ARC 來管理 s1,你不能用 CFRelease() 去釋放 s1。


__bridge_retained:會(huì)將相關(guān)對(duì)象的引用計(jì)數(shù)加 1,并且可以將Core Foundation框架數(shù)據(jù)類型對(duì)象轉(zhuǎn)換為Foundation框架數(shù)據(jù)類型對(duì)象,并從ARC接管對(duì)象的所有權(quán)。

NSString?*s1?=?[[NSString?alloc]?initWithFormat:@"Hello,?%@!",?name];

CFStringRef?s2?=?(__bridge_retained?CFStringRef)s1;

//?or?CFStringRef?s2?=?(CFStringRef)CFBridgingRetain(s1);

//?do?something?with?s2

//...

CFRelease(s2);?//?注意要在使用結(jié)束后加這個(gè)


__bridge_transfer:可以將Foundation框架數(shù)據(jù)類型對(duì)象轉(zhuǎn)換為Core Foundation框架數(shù)據(jù)類型對(duì)象,并且會(huì)將對(duì)象的所有權(quán)交給ARC管理,也就是說引用計(jì)數(shù)交由ARC管理;

__bridge_transfer or CFBridgingRelease



CFStringRef?result?=?CFURLCreateStringByAddingPercentEscapes(.?.?.);

NSString?*s?=?(__bridge_transfer?NSString?*)result;

//or?NSString?*s?=?(NSString?*)CFBridgingRelease(result);

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 在Build Phases -> Compile Sources -> 對(duì)應(yīng)的文件加上-fno-objc-arc的...
    Jadyn_Wu閱讀 609評(píng)論 0 1
  • 歷史 蘋果在 2011 年的時(shí)候,在 WWDC 大會(huì)上提出了自動(dòng)的引用計(jì)數(shù)(ARC)。ARC 背后的原理是依賴編譯...
    壯骨閱讀 658評(píng)論 0 0
  • Objective-C,顧名思義,是一門超C的語(yǔ)言,自從ARC(Auto Reference Count)出現(xiàn)了之...
    xiao彰閱讀 512評(píng)論 0 2
  • Objective-C 和 Swift 語(yǔ)言的內(nèi)存管理方式都是基于引用計(jì)數(shù)「Reference Counting」...
    正經(jīng)的小流氓丶閱讀 236評(píng)論 0 0
  • Tag: 下雨的奈良 鹿大爺 漫山遍野全是鹿 丟失地圖的口袋 從口袋中叼出地圖并咬走吃掉的鹿大爺 使勁拽都拽不出鹿...
    AugustL閱讀 5,139評(píng)論 3 2

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