【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