Reference Count/Retain/Release

Objective-C语言里头每个实例,都是指向某块内存的指针,在C语言当中,你会使用像是malloccalloc这些function来创建内存,用完之后,就调用free释放内存。但是我们如何知道一块内存被多少地方用到,之后这些地方又不再用到呢?所以在Objective-C语言发展之初,就建立了一套计算有多少地方用到某个实例的简单机制,叫做应用计数机制(reference count),意义非常简单:只要一个实例被某个地方用到一次,引用计数器就对这个实例加一,反之就减一,如果数字减到变成了零,就该释放这块内存。

一个内存如果使用allocinit…产生,初始的reference count为1。接着,我们可以使用retain增加reference count。

[anObject retain]; // 加 1

反之就用release

[anObject release]; // 減 1

我们可以使用retainCount检查某个实例被retain了多少次。

NSLog(@"Retain count: %d", [anObject retainCount]);

有了基本概念之后,我们就可以看出以下程式有什么问题

id a = [[NSObject alloc] init];
[a release];
[a release];

因为在第二行,a所指向的内存已经被释放了,所以第三行想要再释放一次,就会造成错误。同样的:

id a = [[NSObject alloc] init];
id b = [[NSObject alloc] init];
b = a;
[a release];
[b release];

在第三行中,由于b指向了a原本所指向的内存区域,但是b原本所指向的内存却没有释放,同时再也没有任何变数指向b原本指向的记内存,因此这块内存就泄漏了。接着,在第四行调用[a release]时,这块内存就已经被放掉了,但是由于a与b都已经指向了同一块内存,所以第五行的[b release]也是操作同一块记忆体,于是会发生EXC_BAD_ACCESS错误。

results matching ""

    No results matching ""