阅读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激活方式详解