6.OC中的内存管理

1.方法的基本使用

OC对象内部都有一个自己的引用计时器,用来表示“对象倍引用的次数”每个引用计时器占用四个字节的存储空间即2^4。对象被创建的时候引用计时器默认值为1;当一个对象计数器值为0的时候,对象占用的内存就会倍系统回收;在整个程序已经退出的时候该程序创建的所有的对象都将被回收。

引用计时器的操作:

当我们给对象发送一条retain消息,可以使引用计时器值+1,retain方法返回对象本身。

给对象发送一条release消息,可以使引用计时器值-1.

可以给对象发送retainCount消息获得当前的引用计数器值;


dealloc:当一个对象要被回收的时候,就会调用。

被释放的对象(所用内存已经被回收):僵尸对象

指向僵尸对象的指针:野指针 给野指针发送消息会报错。

         没有指向任何东西的指针称为空指针(存储的东西是nil、null、0),给空指针发送消息不会报错。

例如:

    Person *p = [[Person alloc]init];
    
    [p release];
    
    p.name = @"Jake";

一般在对象被回收之后要将指针清空:

[p release];
p = nil;

无论以后在怎么操作p都不会报错  OC中不存在空指针错误,给空指针发送消息,不会报错。为了在以后的开发中不产生错误应该开启僵尸对象检测:点击项目名弹出下拉菜单,点击Eidt Scheme ,选定Diagnostics,然后选定僵尸对象检测。


再运行时,空指针就会报错。 messagessent to deallocated instance (地址):


2.多个对象之间的内存管理原则

1.谁想用(占用)某个对象,就用该让对象的计数器+1(让对象做一次retain操作)

         2.不想使用(占用)某个对象,就应该让对象的计数器-1(让对象做一次release)

         3.谁retain ,就让谁release

         4.谁alloc,就让谁release

3.setter的内存管理

内存管理规范:

1.    只要调用了alloc,必须有realease(autorelease)

2.    如果对象不是由alloc创建的就不需要release;

3.    set方法的代码规范

1)  基本数据类型:直接赋值  例如;

- (void)setAge:(int)age
{
    _age = age;
}

2) OC对象类型:

- (void)setCar:(Car *)car
{
    if(car != _car)
    {
        [_car release];
        _car = [car retain];
    }
        
}

4.   property参数的设置(非ARC)

1)        setter内存相关的参数:

     retain:release旧址,retain新值(适用于OC对象类型)

             assign:直接赋值,适用于非OC对象

     copy:release旧址,copy新值

2)       是否要生成setter

    readwrite:同时生成setter和getter声明和实现

    readonly:只会生成getter的声明和实现

3)      多线程管理方面

   nonatomic:性能高(一般用这个)

   atomic :性能低(默认)

4)     setter和getter的名称

  例如:(getter = abc)则调用的时候使用 [p abc];

              (setter = abc;)注意后面的冒号

即使在修改名字之后也可以原来的方法修改  ,这种方法一般用用在bool类型中:

 @property(getter = isRich) bool rich;

调用的时候

 bool  isRich = p.isRich

在以后的@property中,如果对象方法的话加参数retain,即可在生成的setter中加入retain方法。但是在delloc还是要调用retain。将对象多拥有的对象释放(如:人拥有的一本书)。

 

5) 在两个对象相互依赖关系时,比如:人拥有一本书,书被人占用

  为防止互相引用,在.h中@class 来声明类,在.m文件中再import对方的.h文件。

 @class的作用:仅仅告诉编译器,某个名称是一个类,一段在@property中用retain  ,另一端中使用assign。


5.   自定义构造方法

在初始化的时候给定一个初始值,构造方法都是对象方法,一般返回值都是id类型,方法名以initWith开头。代码示例:

- (id)initWithAge:(int)age
{
    if( self = [super init] ) // 先地调用一次super的init 成功以后在进行操作 
			    {
        _age = 10;
    }
    return self; // 最后返回
}


6. autorelease 

为防止对象调用release的位置不合适,在创建对象的时候加入autorelease参数,他会返回对象本身,在对象被创建时放到自动释放池中,在自动释放池被销毁的时候会对池子里所有的对象做一次release操作。在ios程序运行中,会创建无数个池子。这些池子都是以栈结构存在的(先进后出)。

系统自带的方法中,如果不包含alloc、new、copy 那么这些方法返回的对象都是已经autorelease过得:[ NSString stringWithFormat…]


7.    ARC的使用

在使用了ARC的程序中,不需要开发者再管理内存,不允许再调用release、retain、、retainCount,允许重写dealloc,但是不允许调用[super dealloc],当没有强指针指向对象的时候,就会释放对象。在默认情况下,所有的指针都是强指针 __strong,弱指针用 __weak修饰(前面是两个下划线)。

在@property中参数

 strong:成员变量是强指针,相当于原来的retain(适用于OC对象类型)

 weak:成员变量是弱指针,相当于原来的assign(适用于OC对象类型)

 assign:适用于非OC对象

 当两端循环引用的时候,一段用strong 另一端使用weak。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值