引用计数

每个对象都有一个与之相关联多整数,被称作它的引用计数器或保留计算器,当某段代码需要访问一个对象时,该代码就将该对象的保留计数器值加1,表示我要访问该对象,当这段代码访问结束的时候,将对象的保留计数器数值减1,表示不再访问该对象了。当保留计数器的值为0时,表示不再有代码访问该对象了,此时它将被销毁同时占用的内存被回收。

对象的保留计数器值初始值为1。当一个对象即将要被销毁的时候,OC会向对象发送一条dealloc消息,这条消息可以在自己的对象中重写。

常见的几种调用方法:

-(id) retain;

-(oneway void) release;

-(NSUInteger) retainCount;

Eg:

#import <Foundation/Foundation.h>


@interface RetainTra : NSObject


@end


@implementation RetainTra

-(id) init

{

    if (self = [super init]) {

        NSLog(@"init : This is first call -- %d .",[self retainCount]);

    }

    return (self);

}

-(void) dealloc

{

    NSLog(@"dealloc called . Bye Bye..");

    [super dealloc];

}

@end


int main(int argc, const char * argv[]) {

RetainTra *tracker = [ RetainTra new]; //count:1 此处直接调用了init

    

    [tracker retain];//count 2

    NSLog(@"%d--1",[tracker retainCount]);

    

    [tracker retain];//count 3

    NSLog(@"%d--2",[tracker retainCount]);

    

    [tracker release]; //count 2

    NSLog(@"%d--3",[tracker retainCount]);

    

    [tracker release]; //count 1

    NSLog(@"%d--4",[tracker retainCount]);

    

    [tracker release]; //count 0 调用了dealloc。。

    //NSLog(@"%d--5",[tracker retainCount]);

  

    return 0;


}


对象所有权

    如果一个对象内有指向其他对象的实例变量,则称该对象拥有这些对象。如。car对象拥有其指向的engine和tire对象。同样,如果一个函数创建了一个对象,则称该函数拥有这个对象。

访问方法中的保留和释放

    一个更好的解决对象释放问题的代码

-(void) setEngine :(Engine *) newEngine

{

[newEngine retain];

[engine release];

engine = newEngine;

}//setEngine

首先保留了新的engine对象,即使newEngine与engine是同一个对象,保留计数器的值也将先增加,然后立即减少。由于没有归0,engine对象意外的未被销毁,这样避免了错误发生。

在访问方法中,如果先保留新对象,然后再释放对象就不会出现问题了。

自动释放

    不知道为什么,看到这个词的时候,前面一直紧张的内心忽然平静了下来。。。


今天在看引用计数和对象所有权上花了很多时间,加上老师讲了很多关于函数的基础概念,需要慢慢记忆的东西很多。