Chapter 4 : 内存管理

1. NSAutoreleasePool : 自动释放池。

-> 程序可以有多个自动释放池(NSAutoreleasePool)

-> 自动释放池(NSAutoreleasePool)并不包含实际的对象(object/instance)本身,只是包含对释放的对象(object/instance)的引用。

-> 通过对目前的自动释放池(NSAutoreleasePool)发送一条autorelease消息,可将一个对象(object/instance)添加到其中。

 // 自动释放池
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 [pool drain];

2. 引用计数(Retain Count) : 创建对象(object/instance)时,将其引用计数设置为1,每次必须保持此对象(object/instance)时,就发送一条retain消息,使其引用计数加1。

[instance retain];

当不再需要此对象(object/instance)时,通过发送release消息,使其对象(object/instance)引用计数减1.

[instance release];

PS : 当引用计数(Retain Count)为0的时候,系统就会释放它的内存,通过向对象(object/instance)发送dealloc消息。

所以应该这样理解,dealloc是提供给系统来调用的,你不需要去手动的调用一个对象的dealloc。

// 获取一个对象(object/instance)的引用计数
// 返回类型为NSInteger
[instance retainCount];

只要对象(object/instance)的引用计数不为0,系统就不会释放对象(object/instance)使用的内存。

PS :

-> 将对象(object/instance)添加到任何类型的集合(如:NSArray, NSDictionary)中都会使该对象(object/instance)的引用计数增加。而从集合中删除对象(object/instance)则会使引用计数减少。

-> 常量字符串没有引用计数机制,因为永远不能释放这些对象(object/instance)。

示例代码 :

int main(int argc, const char *agrv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
    // Retain Count : 1
    RetainTracker *tracker = [[RetainTracker alloc] init];

    // Retain Count : 2
    [tracker retain];

    // Retain Count : still 2
    [tracker autorelease];

    // Retain Count : 1
    [tracker release];

    NSLog(@"releasing pool");
    // Get nuked, sends release to tracker
    [pool release];

    return 0;
}

3. 访问方法(set and get)中的保留和释放:

原则如下:保持新的,释放旧的,谁拥有对象谁就负责释放对象

- (void)setEngine:(Engine *)newEngine
{
    [newEngine retain];

    // 类成员属性
    [engine release];

    engine = newEngine;
}

4. 内存管理规则:

内存管理规则摘要:

-> 不再使用创建或保持的对象时,释放它们。释放对象,可以释放其所占的内存。

-> 发送release消息不一定能销毁对象,只有Retain Count为0时,系统才会向对象发送dealloc消息来释放它所占的内存。

-> 自动释放池(NSAutoreleasePool)在释放其本身时会自动释放池中的对象。实际细节是,系统向池中的每个对象发送一条

release消息,对引用计数为0的对象发送一条dealloc消息来释放它所占的内存。

-> 如果在某一方法中不再需要一个对象,但需要返回它,可发送一条autorelease消息来将此对象加入到自动释放池中以防止产生内存泄漏(Memory Leak)。

-> 若使用alloc或copy方法(或使用allocWithZone:、copyWithZone:或mutableCopy方法)来直接创建对象,则由你负责释放它。每次retain对象时,都应该release或autorelease。

-> 除上术规则中提到的方法外,不必释放其他方法返回的对象,这不是你的责任。

 

 

posted on 2012-09-27 10:20  BankFish  阅读(207)  评论(0编辑  收藏  举报