iOS之記憶體管理(ARC)

來源:互聯網
上載者:User

標籤:現在   開發   實現原理   objc   www.   jin   run   類型   處理   

iOS的記憶體管理,相信大家都不陌生,之前是使用的MRC,由開發人員手動來管理記憶體,後來使用了ARC,來由系統管理記憶體。本文主要講講Autorelease,Core Foundation對象在記憶體管理方面要注意的地方。

Autorelease

提到記憶體管理,就不得不提autorelease,雖然我們平時開發中很少會感知到它的存在。autorelease就是自動釋放的意思,如果變數使用autorelease來修飾,就表明變數的釋放由系統來完成。

autoreleasepool是由runloop在開啟或者喚醒的時候建立的,當runloop進入睡眠或者釋放掉的時候,autoreleasepool會給pool中的所有對象發送release訊息。那麼,由此便引申出一個問題,如果runloop不進入睡眠或者不釋放(例如:主線程,或者某些常駐線程),pool裡面的對象也便不會被釋放,他們會堆積在記憶體中,但是系統會做一些最佳化,如下:

12345678 - (NSMutableArray*)createArrayNoAutorelease{    id arr = [NSMutableArray arrayWithCapacity:3];    return arr;} - (NSMutableArray*)createArrayAutorelease{    return [NSMutableArray arrayWithCapacity:3];}

上面的兩個方法都是表明的要返回NSMutableArray這個對象,但是兩種寫法不同,系統做的處理也不相同。

我們先調用第一個方法 createArrayNoAutorelease方法,然後使用xcode的Product->Perform Action->Assemble xxx來看看,產生如下代碼:

1234567891011121314151617181920212223 Lfunc_begin1:....前面省略    bl  _objc_retainAutoreleasedReturnValue    .loc    2 56 14                    str r0, [sp, #4]    .loc    2 57 12 is_stmt 1          ldr r0, [sp, #4]    bl  _objc_retain    add r1, sp, #4    movs    r2, #0    .loc    2 58 1                     str r0, [sp]                @ 4-byte Spill    mov r0, r1    mov r1, r2    bl  _objc_storeStrong    ldr r0, [sp]                @ 4-byte Reload    .loc    2 58 1 is_stmt 0           add sp, #16Ltmp3:    pop.w   {r7, lr}    b.w _objc_autoreleaseReturnValueLtmp4:Lfunc_end1:

其中 objc_retainAutoreleasedReturnValue和objc_autoreleaseReturnValue主要用於最佳化程式運行。本來應該將返回的對象註冊到autoreleasepool中,但是有了這兩個函數,就可以不將對象註冊到autoreleasepool中,而是直接傳遞給調用方,這是效能調優的一個舉措。

我們再來看看調用createArrayAutorelease方法,如下:

123456789101112131415 Lfunc_begin0:... 省略    bl  _objc_retainAutoreleasedReturnValue    add r1, sp, #4    movs    r2, #0    .loc    2 44 8                    str r0, [sp, #4]    .loc    2 49 1 is_stmt 1           mov r0, r1    mov r1, r2    bl  _objc_storeStrong    add sp, #24    pop {r7, pc}Ltmp1:Lfunc_end0:

現在對象被註冊到了autoreleasepool中。我們可以使用:

1 po [NSAutoreleasePool showPools]

來看看當前autoreleasepool的狀況,會發現多出了一個對象,如:

(我只截取了一部分)

注意:對於alloc/new/copy/mutableCopy這樣的方法作為返回對象,編譯器會將他們最佳化為createArrayNoAutorelease相同的情況

關於autoreleasepool的內部結構,實現原理等,可以參看:

http://www.cocoachina.com/ios/20150610/12093.html

Core Foundation

Core Foundation對象是一組由c語言介面,可以跟Foundation架構的OC對象相互轉換。

要搞清楚Core Foundation對象的記憶體管理,就需要搞清楚:__bridge, __bridge_retained, __bridge_transfer; CFRetain(), CFRelease() 這幾個關鍵詞的概念。

CFRetain(), CFRelease() :Core Foundation對象的記憶體管理方式,跟之前MRC時代的retain和release很像。

    {        CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, "test", kCFStringEncodingUTF8);        NSLog(@"%@", str);        CFRelease(str);    }

注意:這裡要調用CFRelease(str)方法,不然會有記憶體流失。

__bridge:只做類型轉換,不修改對象持有人。如下:

    {        CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, "test", kCFStringEncodingUTF8);        NSString *obj = (__bridge NSString*)str;        NSLog(@"%@", obj);//        CFRelease(str);    }

對於從CF轉換為OC對象,一定要調用CFRelease(str)方法,不然會有記憶體流失,因為只是做了簡單的指標地址變換,str仍然沒有釋放。

來看一個野指標的例子:

    CFMutableArrayRef cfObject = NULL;    {        id obj = [[NSMutableArray alloc] init];        cfObject = (__bridge CFMutableArrayRef)obj;        CFShow(cfObject);    }    CFRelease(cfObject);

因為__bridge不持有obj對象,所以當大括弧結束以後,obj被釋放,cfObject就成為了野指標,在調用CFRelease方法時就會引發程式崩潰。

__bridge_retained:用於將OC對象轉換為CF對象,持有人也發生改變,需要調用CFRelease方法。

__bridge_transfer:將CF對象轉換為OC對象,同時將對象持有權交給ARC,不需要調用CFRelease方法,如下:

    {        CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, "test", kCFStringEncodingUTF8);        NSString *obj = (__bridge_transfer NSString*)str;        NSLog(@"%@", obj);//        CFRelease(str);    }

所以在使用CF對象時,要特別注意記憶體問題。

 

參考文章:

https://yq.aliyun.com/articles/58964

https://juejin.im/entry/579bfdfe5bbb500064d18aca

iOS之記憶體管理(ARC)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.