ARC學習筆記

來源:互聯網
上載者:User

1. ARC並不是自動管理記憶體,與AutoreleasePool不同,ARC是LLVM 3.0編譯器提供的特性,編譯器自動在適當的地方插入retain、release、autorelease,所以還是手動管理記憶體,對象不會像AutoreleasePool一樣在記憶體中存放很久。

2. ARC只能工作於Objective-C對象,如果應用使用了Core Foundation或malloc()/free(),此時需要你來管理記憶體。

3. 雖然ARC管理retain和release,但並不表示不需要處理記憶體問題,strong指標會保持對象的生命,所以有時候為了回收記憶體,自己要將其設為nil,以便釋放記憶體,否則記憶體可能會被用光。

4. property的修飾符有一定變化。a)strong等同於retain;b)weak是弱指標,當對象釋放時會自動化佈建為nil;c)unsafe_unretained等同於assign只有iOS4才應該使用;d)copy和以前的copy一樣,複製一個對象並建立strong關聯;e)assign不能用於對象,應該用於BOOL、int和float等實值型別。

5. 如果dealloc方法只是釋放對象,則不需要此方法,但如果dealloc中處理了其它非記憶體資源釋放,如定時器、Core Foundation對象,則仍然需要在dealloc方法中進行手動釋放,但不能調用[super dealloc]。

6. 由於ARC只作用於Objective-C對象,有時候要用到Core Foundation對象,兩者之間的轉換可以使用toll-free bridging來很方便地完成,例如NSString和CFStringRef。編譯器必須知道由誰來負責釋放轉換後的對象,如果你把一個Objective-C對象當作Core Foundation對象來使用,ARC將不再負責釋放該對象,在兩種對象之間進行轉換時,要顯示地移交或者接受權利。

7. 函數參數和局部變數一樣,都是strong指標,這種對象在函數入口處會被retain,並且對象會持續存在直到指標被銷毀。

8. 

1 - (NSString *)escape:(NSString *)text {2     return [(NSString *)CFURLCreateStringByAddingPercentEscapes(3                         NULL,4                         (CFStringRef)text, // 這裡需要進行bridging casts,將text臨時當作CFStringRef對象來使用。5                         NULL,6                         (CFStringRef)@"!*'();:@&=+$,/?%#[]", // 這裡不用bridging casts,因為這是常量,不需要釋放!7                         CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)) 8             autorelease];9 }

 

9. __bridge轉換不僅僅局限於Core Foundation對象,某些API使用void *指標作為參數,允許你傳遞任何東西的引用,比如Objective-C對象、Core Foundation對象或malloc()記憶體緩衝區等等。那麼傳參數的時候將這些對象轉換為void *,如:[UIView beginAnimations:nil context:(__bridge void *)someObject],在使用這些參數的地方再將其轉換回來,如:MyClass *myObject = (__bridge MyClass *)context。

10. 記憶體管理權的移交有三種情況,a)使用CFBridgingRelease()或__bridge_transfer將管理僅移交給Objective-C;b)使用CFBridgingRetain()或__bridge_retained將管理權移交給Core Foundation;c)使用__bridge來臨時使用某對象,不改變管理權。

11. 在ARC之前只有成員變數才會預設設為nil,在arc中局部對象指標會被設為nil,局部實值型別和實值型別指標還是隨機數。

12. 所有的Core Foundation物件類型都與Objective-C能夠toll-free bridged,但是UIColor不能,因為UIColor與CGColor並不是toll-free bridged,所以把CGColor放入NSArray要強制轉換為id類型。

13. property中的屬性名稱不能以new開頭,除非將getter指定指定為另外一個名字,@property NSString *newTitle;會出錯,@property (getter=theNewTitle) NSString *newTitle;正確。

14. autorelease pool變成了一種語言結構,而不是以前的類,@autoreleasepool{}比NSAutoreleasePool快六倍。在一個很大的迴圈中,有時候迴圈xx次進行一次NSAutoreleasePool清除工作,但其實這是不必要的,每迴圈一次清一次也無所謂,現在@autoreleasepool指令比NSAutoreleasePool快六倍,在迴圈中直接使用也不用擔心效能問題。

15. block會捕獲自己使用到的所有變數,如果用到成員變數,那麼成員變數所在的類會被retain,這樣這個類就不會被釋放,解決辦法是使用局部變數,NSString *text = self.artistName;,然後在block中使用text,而不是self.artistName,就不會出現問題。

16. 有時候block避免不了使用self對象,ARC以前可以建立一個局部的__block對象,把self值賦值過去,如:__block MyClass *blockSelf = self;,在block中引用這個__block局部變數來訪問self的屬性都不會retain self,但是在ARC中即使使用了__block來標記這個局部變數,它也是強引用的,這時__block的唯一功能是允許你修改已捕獲的變數。ARC的解決辦法是定義弱引用:__weak MyClass *weakSelf = self;,這樣weakSelf引用了self,但不進行retain,在block中捕獲weakSelf而不是self,因此不存在所有權迴環。在簡單應用中block屬於self,所以block不可能在self被釋放後還能被調用,有時候在block中檢查這個weakSelf被認為是不必要的,但是如果block被非同步呼叫,則建立強引用來保持對象存活就有必要了,因此在ARC中使用block,而且要避免捕獲self,可以這樣:

 1 - (void)doSomething 2 { 3     __weak weakSelf = self; 4     block = ^() { 5         id strongSelf = weakSelf; 6         if ( strongSelf != nil ) { 7             // do stuff with strongSelf 8         } 9     };10 }

 

17. 如果建立一個對象,等待5秒後執行某一block,然後釋放掉該對象,在ARC以前應該這樣:

1 - (void)doSomething2 {3     MyClass *object = [[MyClass alloc] init];4     object.block = ^(void) {5         // do stuff6         [object autorelease];7     };8     [object launchAfter:5];9 }

 

在ARC中不允許使用autorelease,所以去掉釋放那一行,那麼這樣會導致block永遠不會被執行,因為object對象在此函數返回後被釋放。解決辦法是定義__block類型變數,這種類型是強引用,且block中能修改其值,然後在block中將些變數設為nil,如下:

1 - (void)doSomething2 {3     __block MyClass *object = [[MyClass alloc] init];4     object.block = ^(void) {5         // do stuff6         object = nil;7     };8     [object launchAfter:5];9 }

 

18. 

1 - (void)doSomething2 {3     NSString *string;4     @autoreleasepool {5         string = [NSString stringWithFormat:…];6     }7     // the string object is still alive here8 }

 

19. 

1 - (void)doSomething2 {3     __autoreleasing NSString *string;4     @autoreleasepool {5         string = [NSString stringWithFormat:…];6     }7     // the string object is still deallocated here8     NSLog(@"%@", string); // crash!9 }

 

20. 編寫自己的out-parameter方法:

 1 - (NSString *)fetchKeyAndValue:(__autoreleasing NSNumber **)theValue 2 { 3     NSString *theKey; 4     NSNumber *theValue; 5      6     // do whatever you need to do here 7      8     *value = theValue; 9     return theKey;10 }

 

21. Core Foundation對象不能autorelease,autorelease完全純屬於Objective-C,有些人通過轉換Core Foundation對象為id,再調用autorelease,這在ARC中明顯不能工作,因為不能調用autorelease。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.