【iPhone 編程】alloc, retain, release 和 copy 的概念
作為一個從學習 C++,Java 開始的程式員,iPhone 編程所帶來的最大挑戰莫過於reference count 的概念。
剛開始接觸 Objective C,在 XCode 裡摸來摸去,總免不了要跟這傢夥碰麵:
相信我,看見它多數的原因都是
reference count 的概念搞不清楚所引致的。
首先我們知道,要使用一個 object 的時候,我們必須要給它一個落腳的地方,且我們必須告訴係統說這一塊 memory 是我們擁有的,請不要擅自將在裡頭居住的 object 趕走。這就是我們平時寫 alloc 時所做的事情:
1
|
NSString *exampleString
= [[ NSString alloc]
init];
|
分配(allocate)了一塊 memory 後,係統便會自動紀錄此 object 的 retain count 為 “1″。意即:這 object 正被一個名為 “exampleString” 的變數所擁有/聯繫著。若我們的程式某處也想擁有這個 object,我們可以:
1
|
NSString *anotherString
= [exampleString retain];
|
把這個 object 的 retain count 加一(= 2)。這樣做的話,我們就不必擔心若 exampleString有什麼三長兩短,anotherString 也受到牽連。
當然,能夠擁有一個 object,自然也能放棄它。在這裡我們用 “release”。如以上例子,當我們已不再需要 exampleString,我們可以放棄 exampleString 對這個 object 的擁有權:
1
|
[exampleString
release];
|
這樣做便把這 object 的 retain count 減一,變為 1。意思是這 object 還有一個擁有者,那就是 anotherString 了。當我們決定了要完全釋放這個 object(deallocate)時,可以通過release anotherString,把 retain count 變0。這時,係統便會自動清除它了。
當然,如果你沒有適當地 retain,又狂妄地 release object 的時候,就會遇見上麵提到的那個傢夥了。會出現 bad access 錯誤的原因就是係統根本找不到你所要釋放的東西。
要弄清除的概念是,
retain 不代表分配了一個新的 memory
筆者便曾經搞錯了這個概念。如果你想要複製一個object,你所需要的指令是 “copy”。
1
2
|
MyObject
*originalObject = [[MyObject alloc] init];
MyObject
*duplicatedObject = [originalObject copy ];
|
以上兩行指令已經分配了兩塊 memory。對其中一個 object 所做的改變,不會影響到另外一個,且他們各自的 retain count 為1。
應該說明的是,由於 object 的性質各有不同,如果有需要用到copy指令,你應該為你的object class 加入 -(id)copyWithZone:(NSZone*)zone 函數。有興趣知道更多的話,可以到這裡參考。
最後更新:2017-04-04 07:03:16