内存管理


常用术语解释

1.为什么要进行内存管理

(1)大家都知道苹果的手机即使512运行也很流畅,关键在于苹果的软件对内存管理的严谨,这也是oc的一个特色之处。我们程序员在开发中更得注意内存的管理,以免内存泄漏,下面说一些有关内存管理的知识。

(2)任何继承了NSObject的对象,都需要内存管理,因为这些系统不会自动回收

(3)对其他数据类型(int,char,float,double,struct,enum),不需要内存管理,因为这个数据类型系统会自己回收。


2.计数器。在oc中会对对象的使用情况有个记录,这就是计数器的概念。

 (1)retain :计数器+1,会返回对象本身
 (2) release :计数器-1,没有返回值
 (3) retainCount :获取当前的计数器
 (4)alloc

 (5)当使用alloc、new或者copy创建一个新对象时,新对象的引用计数器默认就是1
 (6)当一个对象的引用计数器值为0时,对象占用的内存就会被系统回收。换句话说,如果对象的计数器不为0,那么在整个程序运行过程,它占用的内存就不可能被回收,除非整个程序已经退出
  * 当一个对象要被回收的时候,就会调用
  * 一定要调用[super dealloc],这句调用要放在最后。

3.对象的销毁 
(1)当一个对象的引用计数器值为0时,那么它将被销毁,其占用的内存被系统回收 
(2)当一个对象被销毁时,系统会自动向对象发送一条dealloc消息 
(3) 一般会重写dealloc方法,在这里释放相关资源,dealloc就像对象的遗言 
(4) 一旦重写了dealloc方法,就必须调用[super dealloc],并且放在最后面调用 
不要直接调用dealloc方法 
(5) 一旦对象被回收了,它占用的内存就不再可用,坚持使用会导致程序崩溃(野指针错误)

4.野指针 
“野指针”不是NULL指针,是指向被释放的或者访问受限的垃圾内存的指针。

内存管理原则 

(1)谁创建,谁release 

(2)如果你通过alloc、new或[mutable]copy来创建一个对象,就调用release或autorelease来使计数器减掉一。

(3)谁retain,谁release 

(4)只要你调用了retain,无论这个对象是如何生成的,就调用release或者autorelease。
总之一个原则,只要retain了就得release。只要有让计数器加一的操作,就必须得有使计数器减一的操作。

set方法的内存管理

由上面的知识可知,如果你的成员变量中有oc类型的,你就必须对它进行内存管理。
示例:
- (void)setCar:(Car *)Car
{
 
    if( Car !=_Car)// 先判断是不是新传进来的对象
{
[_Car release];// 既然有了新的对象,就需要释放原先的对象 

_Car = [Car retain]; // 新对象做一次retain,是计数器加1
} 

}

由于做了一次retain操作,所以应该使用地dealloc进行释放,
dealloc代码规范
1.一定要[super dealloc],而且要放在最后面
2.对self(当前)所拥有的其他对象做一次release。
示例:
- (void)dealloc
{
[_Car realease];// 这个类中所有对象成员变量都需要做一次release
[super dealloc];后面必须调用父类的dealloc方法 
}

总之把我一下几个原则:

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

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

(3)尽量不要使用,因为匿名对象会导致内存泄露

(4)谁retain,谁release

(5)谁alloc,谁release

@property的内存管理

1.oc对象类型
@proerty (nonatomic ,retain)类名 *属性名
例子 @property(nonatmic,retain)Car *car
        @property (nonatomic,retain)id car
2.非oc对象(int \enum\struct)
@property (nonatomic,assign) 类型名称 属性名;
例子  @property(nonatomic,assign) int age

其中nonatomic:性能高(以后就写这个)
atomic:性能低(默认)
retain:release旧值,retain新值(适用于OC对象)。
assign:直接赋值,不做任何内存管理(默认,用于非OC对象类型)

自动释放——autorealease


1.系统自带的方法中,如果不包含alloc、copy、new,那么这些方法对象都是autorealease过的。
例子 [NSString stringWithFormat ;...];
2.autorelease的使用
(1)某个对象收到autorelease消息(方法)时,这个对象加到一个自动释放池中
(2)当自动释放池销毁时,会给池子里面的所有对象发送一条release消息(做一次release操作)
(3)调用autorelease方法时并不会改变对象的计数器,并且会返回对象本身
(4)autorelease实际上只是把对release的调用延迟了,对于每一次autorelease,系统只是把该对象放入了autorelease pool中,当该pool被释放时,该pool中的所有对象会被调用Release
3.autorelease的优势和使用注意事项
(1)不用再关心对象释放的时间
(2)不用再关心什么时候调用release
(3)占用内存较大的对象不要随便使用autorelease
(4)占用内存较小的对象使用autorelease,没有太大影响
示例:
#import <Foundation/Foundation.h>

@interface Person : NSObject

@property (nonatomic, assign) int age;

@end
@implementation Person
- (void)dealloc
{
    NSLog(@"Person---dealloc");
    
    [super dealloc];
}
@end
int main()
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
    Person *pp = [[[Person alloc] init] autorelease];
    
    [pool release]; // [pool drain];
    
    @autoreleasepool
    {
        
        // 1
        Person *p = [[[[Person alloc] init] autorelease] autorelease];
        
        // 0
        // [p release];
    }
    
    return 0;
}


void test()
{
    @autoreleasepool
    {// { 开始代表创建了释放池
        
        // autorelease方法会返回对象本身
        // 调用完autorelease方法后,对象的计数器不变
        // autorelease会将对象放到一个自动释放池中
        // 当自动释放池被销毁时,会对池子里面的所有对象做一次release操作
        Person *p = [[[Person alloc] init] autorelease];
        
        p.age = 10;
        
        
        
        @autoreleasepool
        {
            // 1
            Person *p2 = [[[Person alloc] init] autorelease];
            p2.age = 10;
            
            
        }
        
        
        Person *p3 = [[[Person alloc] init] autorelease];
        
        
    } // } 结束代表销毁释放池
}

ARC机制
1.ARC的判断准则:只要没有强指针指向对象,就会释放对象
2.指针分2种:
 1> 强指针:默认情况下,所有的指针都是强指针 __strong
 2> 弱指针:__weak
3.ARC特点
 1> 不允许调用release、retain、retainCount
 2> 允许重写dealloc,但是不允许调用[super dealloc]
 3> @property的参数
  * strong :成员变量是强指针(适用于OC对象类型)
  * weak :成员变量是弱指针(适用于OC对象类型)
  * assign : 适用于非OC对象类型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值