1. 程式人生 > >【Objective-C高階程式設計】iOS與OS X多執行緒和記憶體管理

【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_transfer

13. GNUstep 跟 cocoa 框架可以替換。