【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 函數。有興趣知道更多的話,可以到這裡參考。

时间: 2024-08-19 22:19:34

【iPhone 編程】alloc, retain, release 和 copy 的概念的相关文章

VB編程規約

VB編程規約 jugnlesong 1. 對象命名規約 對象種類 對象名稱 對象前綴 例 FORM 窗體 frm frmMain MDI 子窗體 子窗體 mdi mdiNote PICTURE BOX 圖片控件 pic picView LABEL 標籤控件 lbl lblMessage TEXT BOX 文本控件 txt txtPassword FRAME 框架控件 fra fraOption COMMAND BUTTON 命令控件 cmd cmdClose CHECK BUTTON 復選框 c

c++-windows shell編程 的一些小疑問 win7 64位操作系統 vs2003工具

问题描述 windows shell編程 的一些小疑問 win7 64位操作系統 vs2003工具 win7上编写的一个window shell 用于 右键文件时 添加一个私人的菜单并弹出一个提示对话框. 现在出现有一个bug 在桌面(explore.exe)右键没有效果 但是在其他程序中有效果. 例如我打开vs2003工程 file -> Open Project 弹出一个选择工程的窗口. 在这个窗口里面 右键 出现了我添加的那个 menu. 以前在xp上面没有这个bug 但是现在在 win7

編程 未來-已決定要選擇C/C++當我的主要語言,該如何使用他們增加編程的技術呢???

问题描述 已決定要選擇C/C++當我的主要語言,該如何使用他們增加編程的技術呢??? 基礎可說是打好了,但是由 進階->深入 這個過程似乎非常模糊,看完一些MFC,windowsAPI和C語言的網路編程之後,感覺編程並沒有太大的進步.....請高手指引

android編程開啟GPS功能

问题描述 在android系統中將GPS功能關閉的狀態下,怎樣通過編程的方式將其開啟? 解决方案 解决方案二:這個,你可以慢慢研究研究!

c#高級編程記錄--第一章

C#有一個基於值類型和引用類型之間區別為基礎的類型系統: 相關概念:CLR.受管制代碼.非受管制代碼.CTS.CLS.裝配件.反射.裝配件清單.應用域.無用存儲單元收集 .NET程序包含多個裝配件,其中一個裝配件被指定為一個可執行程序,包含主程序的啓動入口點,其他的裝配件則被指定為庫 編譯.運行:* .CS--〉裝配件(IL.元數據)--〉CLR(JIT編譯(獲取安全許可.内存類型檢查.應用域).無用内存單元檢查與收集.com交換操作服務) 值類型:變量保存值,存在堆棧中 引用類型:變量保存地址

C#数据库編程2

数据|数据库 四.插入数据记录: </P><P> 对数据库进行插入记录操作和删除记录操作基本的思路是一致的,就是通过ADO.NET首先插入数据记录到数据库,然后对"DataSet"对象进行必要的修改.下列代码就是以Access 2000数据库为模型修改当前记录的代码: </P><P>protected void Update_record ( object sender , System.EventArgs e ) { int i = m

window ce 編程問題

问题描述 我用的是vs2005进行windowce编程,现我通过webservice进行网络上数据库方面的数据处理,同样的webservice在cs或web上都能调用而且也能得到所需结果,但是在windowce中却报"無法调用"SmartData.WebService.Service.Qry()",因为它是Web方法,"请指教,或有什么更好的进行windowce对网络数据库方面的编程方法介绍. 解决方案 解决方案二:看WebService类似乎没有精简版可以通过SQ

編程

问题描述 用c#随机输出7到15的整数,每个数输出20遍 解决方案 解决方案二:vararr=Enumerable.Range(7,8);for(vari=0;i<20;i++){arr.OrderBy(i=>Guid.NewGuid()).ToList().ForEach((x)=>{Console.WriteLine(x);});} 解决方案三:题目不明确,什么叫每个数输出20遍,产生几个数,是否允许重复.解决方案四:这个问题是要解决随机问题,还是逻辑问题?随机实现很简单Radom_

iOS 进阶—— iOS内存管理

1 似乎每个人在学习 iOS 过程中都考虑过的问题 alloc retain release delloc 做了什么? autoreleasepool 是怎样实现的? __unsafe_unretained 是什么? Block 是怎样实现的 什么时候会引起循环引用,什么时候不会引起循环引用? 所以我将在本篇博文中详细的从 ARC 解释到 iOS 的内存管理,以及 Block 相关的原理.源码. 2 从 ARC 说起 说 iOS 的内存管理,就不得不从 ARC(Automatic Referen