OC学习那些事:内存管理

1.范围

任何继承了NSObject的对象,对基本数据类型无效

2.原理

每个对象内部都保存了一个与之相关联的整数,称为引用计数器

当使用alloc、new或者copy创建一个对象的时,对象的引用计数器设置为1。

给对象发送一条retain消息,可以使引用计数器+1

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

当一个对象的引用计数器值为0时,那么它将被销毁,其占用的内存被系统收回。OC也会自动发送一条dealloc消息,一般会重写dealloc方法,在这里做释放相关的资源。一定不要直接调用dealloc方法。

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

3.原则

谁创建,谁释放(”谁污染、谁治理“)。如果你通过alloc、new或(mutable)copy来创建一个对象,那么你必须调用release和autorelease。换句话说,不是你创建的,就不用你去释放

一般来说除了alloc、new或copy之外的方法创建的对象,都声明了autorelease

谁retain,谁release。只要你调用了retain,无论这个对象是如何生成的,你都要调用release

4.注释

#pragma mark -分组 
#pragma mark 方法注释 
 
#pragma mark - 公共方法 
#pragma mark 读书 
-(void)readBook 
{ 
    NSLog(@"当前读的书是:%f",_book.prize); 
} 

5.set方法的内存管理

1.普通类型:只需要@propertyintage;

2.OC类型:需要@propertyBook*book,声明属性,实现set方法(先判断是否相等,release旧的,retain新的),在dealloc:方法中release;

-(void)setBook:(Book *)book 
{ 
    if (_book != book) { 
        //先释放旧的成员变量 
        [_book release]; 
        //在retain新传进来的对象 
        _book = [book retain]; 
    } 
} 
 
#pragma mark 回收对象 
- (void)dealloc 
{ 
    [_book release]; 
    NSLog(@"student:%i 被销毁了",_age); 
    [super dealloc]; 
} 

6.空指针和野指针

空指针:不报错

[nil release];

野指针:访问了不属于你的内存,会报错

[sturelease];

//野指针

[sturelease];

7.@property参数

1.读写属性:

readwrite(默认)

readonly:只生成get方法声明

2.setter处理

assign(默认)

retain:在setter方法中,release旧值,retain新值

copy:在setter方法,release旧值,copy新值

3.原子性:

atomicity(默认)

atomicity:给方法进行枷锁,保证多线程安全

4.getter/setter方法

getter=isRich/setter=rich

getter:指定getter方法的方法名

8.自动释放池(autoreleasepool)

自动释放池也是OC里面一种内存自动回收机制,一般可以将一些临时变量添加到自动释放池中,统一回收释放

当自动释放被销毁的时候,池里的所有对象,都会调用一次release方法

@autoreleasepool{}:手动创建一个自动释放池。 
 @autoreleasepool { 
        Student *stu = [[Student alloc]init]; 
        [stu release]; 
    } 
 
//iOS5.0前 
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; 
… … 
[pool release]; 

9.autorelease

OC对象只需要发送一条autorelease消息,就会把这个对象添加到最近的自动释放池中(栈顶的释放池)。

autorelease实际上只是把release调用延迟了,对于每一次autolease,系统只是把该对象放入了当前的autoreleasepool中,当该pool被释放时,该pool中的所有对象都会调用release方法

10.autoreleasepool注意

在ARC下,不能使用[[NSAutoreleasePoolalloc]init]创建自动释放池,应当使用@autoreleasepool

不要把大量的循环操作放到同一个NSAutoreleasePool之间,这样会造成内存峰值上升

尽量避免对大内存使用该方法,对于这种延迟释放机制,还是尽量少用

sdk一般利用静态方法创建并返回对象都是已经autorelease的,不需要再进行release操作

你可能感兴趣的:(内存管理)