【Objective-C高階程式設計】iOS與OS X多執行緒和記憶體管理
1. __weak修飾符的優點,除了解決迴圈引用的問題,在持有某物件的弱引用時,若該物件被廢棄,則此弱引用將自動失效並且處於nil被賦值的狀態(空弱引用)。
如:
id __wark obj1 = nil;
{
id _strong obj0 = [[NSObject alloc] init];
obj1 = obj0;
NSLog(@"A: %@", obj1);
}
NSLog(@"B: %@", obj1);
A:<NSObject: 0x111111>
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_transfer13. GNUstep 跟 cocoa 框架可以替換。