1. __weak修飾符的優點,除瞭解決循環引用的問題,在持有某對象的弱引用時,若該對象被廢棄,則此弱引用將自動失效並且處於nil被賦值的狀態(空弱引用)。
如:
id __wark obj1 = nil; { id _strong obj0 = [[NSObject alloc] init]; obj1 = obj0; NSLog(@"A: %@", obj1); } NSLog(@"B: %@", obj1); A: B:(null)
2. 盡管ARC式的內存管理時編譯器的工作,但附有 __unsafe_unretained 修飾符的變量不屬於編譯器的內存管理對象。
3. __weak 修飾符隻能用於ios5以上以及OS X Lion 以上版本的應用程序。
4.將生成的對象直接賦給__weak 或者__unsafe_unretained 的變量會產生警告 [-Warc-unsage-ratained-assign];
需將強引用的對象賦值給__weak 或者__unsafe_unretained 的變量。
5. 在ARC下,使用@autoreleasepool塊來替代“NSAutoreleasePool類對象生成、持有及廢棄”這一范圍。
@autoreleasepool { id _autoreleaseing obj = [[NSObject alloc] init]; }
6. obj為強引用,自己持有對象。該對象由編譯器判斷其方法後,自動註冊到autoreleasepool,因為變量obj超出瞭作用域,強引用失效,所以自動釋放瞭自己持有的對象。
同時隨著@autoreleasepool塊的結束,註冊到autoreleasepool中的所有對象被自動釋放。因為對象的所有者不存在,所以廢棄對象。
@autoreleasepool { id _strong obj = [NSMutableArray array]; }
7. 為瞭防止_weak 變量在訪問引用對象的過程中,該對象有可能被廢棄,故而把要訪問的對象註冊到autoreleasepool中,那麼在@autoreleasepool塊結束之前都能確保該對象存在。
8. id *obj 的全式是 id _autoreleasing *obj;
同樣的是: NSObject **obj 為 NSObject *__autoreleasing * obj;
- (BOOL)performOperationWithError:(NSError **)error; - (BOOL)preformOperationWithError:(NSError * __autoreleasing *)error;
9.
- (BOOL)preformOperationWithError:(NSError * __autoreleasing *)error; { //error *error = [[NSError alloc] initWithDomain:MyAppDomain code:errorCode userInfo:nil]; return NO; }
NSError *error = nil; BOOL result = [obj performOperationWithError:&error];
NSError __strong *error = nil; NSError __autoreleasing *tmp = error; BOOL result = [obj performOperationWithError:&tmp]; error = tmp;
10. 顯示指定__autoreleasing 修飾符時,必須註意對象變量要為自動變量(包括局部變量、函數以及方法參數)。
11. 打印autoreleasepool 的調試信息
// 函數聲明 extern void _objc_autoreleasePoolPrint(); // 開始調試 _objc_autoreleasePoolPrint();
12. ARC規則
①不能使用 retain、release、reatainCount/autorelease
②不能使用 NSAllocateObject/NSDeallocateObject;
③需遵守內存管理的方法命名規則
(alloc/new/copy/mutableCopy)
④不要現實調用dealloc
⑤使用@autoreleasepool塊代替NSAutoreleasePool
⑥不能使用區域(NSZone)
⑦對象型變量作為C語言結構體(struct/union)的成員
因為ARC把內存管理的工作分配給編譯器,所以編譯器必須能夠知道並管理對象的生存周期。
C語言的自動變量(局部變量)可使用該變量的作用域管理對象。
但對於C語言的結構體成員來說,這在標準上是不可實現的。
但可以強制轉換為 void *,或者附加 __unsafe_unretained 修飾符。
(附有 __unsafe_unretained 修飾符的變量不屬於編譯器的內存管理對象。)
struct Data{ NSMutableArray __unsafe_unretained *array; };
⑧顯示轉換(id) 和(void*)
非ARC下兩者可以轉換,在ARC下兩者的轉換需借助 __bridge
id obj = [[NSObject alloc] init]; void *p = (__bridge void *)obj; id o = (_bridge id)p;
擴展:__btidge_retained __bridge_transfer
13. GNUstep 跟 cocoa 框架可以替換。