閱讀889 返回首頁    go 阿裏雲 go 技術社區[雲棲]


【iPhone 編程】alloc, retain, release 和 copy 的概念

作為一個從學習 C++,Java 開始的程式員,iPhone 編程所帶來的最大挑戰莫過於reference count 的概念。

剛開始接觸 Objective C,在 XCode 裡摸來摸去,總免不了要跟這傢夥碰麵: 

相信我,看見它多數的原因都是 reference count 的概念搞不清楚所引致的。 

首先我們知道,要使用一個 object 的時候,我們必須要給它一個落腳的地方,且我們必須告訴係統說這一塊 memory 是我們擁有的,請不要擅自將在裡頭居住的 object 趕走。這就是我們平時寫 alloc 時所做的事情:

?
1
NSString*exampleString = [[NSStringalloc] 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

  上一篇:go 學習 nasm 語言
  下一篇:go 體驗全功能:Win 8激活方式詳解