干柴

黑马程序员 内存管理

1、什么是内存管理
  • 内存管理是关于如何管理对象生命周期的编程原则
  • OC的内存管理只针对于对象,基本数据类型不需要管理内存
  • 当以一个对象没有再被使用时,应该从内存中释放掉
  • 所以的对象都有一个计数器,叫做引用计数(retainCount),表示该对象当前被多少“人”在使用。
  • 当引用计数为0时,系统会销魂该对象


2、alloc、retain、release

  • alloc用来创建对象,对象创建完成后,计数为1,只被调用一次。
  • retain使引用计数+1,可被调用多次。
  • relese使引用计数-1,可被调用多次。
  • 当引用计算为0,该对象会被销魂,在销魂之前会调用dealloc方法

Student *student=[[Student alloc] init];
NSLog(@"alloc后的retainCount=%ld",student.retainCount);

[student retain];
NSLog(@"第一次retain后的retainCount=%ld",student.retainCount);

[student retain];
NSLog(@"第二次retain后的retainCount=%ld",student.retainCount);

[student release];
NSLog(@"第一次release后的retainCount=%ld",student.retainCount);

[student release];
NSLog(@"第二次release后的retainCount=%ld",student.retainCount);

//第三release后retainCount=0,对象被销魂
[student release];

  • 为了知道对象是否被销魂了,我们应该重写dealloc方法,注意要调用[super dealloc];

@implementation Student
- (void)dealloc
{


[super dealloc];
NSLog(@"销魂了");
}

@end

  • 打印的结果

黑马程序员 内存管理 - huang_sheng_sen - huang_sheng_sen的博客

 
  • 如果提示不能alloc、retain、release,说明项目的Automatic Refrence Counting设置成了YES,修改方法

黑马程序员 内存管理 - huang_sheng_sen - huang_sheng_sen的博客

 


3、对象所以权

  • 当一个所有者(本身也是对象)做了alloc、retain、[mutable]copy这些动作,它就拥有了一个对象的所有权
  • 使用release、autorelease释放对象所有权

黑马程序员 内存管理 - huang_sheng_sen - huang_sheng_sen的博客


4、黄金法则

如何一个对象是用来alloc,[mutable]copy,retain,那必须使用对应的release或autorelease释放,保证内存平衡。

   

5、如何持有一个对象

黑马程序员 内存管理 - huang_sheng_sen - huang_sheng_sen的博客

  • set方法持有对象所以权

-(void)setBook:(Book *)book

{

    //如果是同一个对象就不必再设置了

    if (_book!=book) {

        [_book release];//释放掉之前的所有权

        _book=[book retain];//retain获得新对象的所有权

    }

}


  • 自定义初始化方法,持有对象所有权

- (instancetype)initWithBook:(Book *)book

{

    if (self=[super init]) {

        _book=[book retain];

    }

    return self;

}

  • dealloc方法
    • 当对象被销毁时,对调用dealloc方法,应该在dealloc方法中释放其他对象的所有权

- (void)dealloc

{

    [super dealloc];

    [_book release];

    NSLog(@"销毁了");

}


6、数组的内存管理 

NSMutableArray *books=[NSMutableArray array];

Book *book1=[[Book alloc] init];
Book *book2=[[Book alloc] init];
[books addObject:book1];//book1会被数组retain,计数+1
[books addObject:book2];//book2会被数组retain,计数+1

//黄金法则,alloc对应release,成对出现
[book1 release];
[book2 release];

  • 数组销毁时或者调用removeAllObjects方法时,会对数组内存每一个元素发送release消息

[books removeAllObjects];

  • 移除对于下标的元素的同时,会对它发送release消息

[books removeObjectAtIndex:0];


7、自动释放池

  • 自动释放池是OC的一种内存自动管理机制
  • 当自动释放池销毁时,它会对池内的所有对象调用一次release方法
  • 当我们向一个对象发送autorelease消息时,这个对象就被放入到自动释放池中

@autoreleasepool {

Book *book1=[[Book alloc] init];

//加入到自动释放池

[book1 autorelease];

  • 在autoreleasepool以外调用autorelease,则该对象就不归这个自动释放池管
  • 自动释放池可以嵌套使用
  • autorelease会将对象放到离它最近的自动释放池

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

//自动释放池1
@autoreleasepool {

Book *book1=[[Book alloc] init];
Book *book2=[[Book alloc] init];
//自动释放池2
@autoreleasepool {

[book1 autorelease];//book1归自动释放池2管,
}//程序走过这个括号后,自动释放池2就会被销魂,book1会被release

//book2归自动释放池1管
[book2 autorelease];

}//程序走过这个括号后,自动释放池1就会被销魂,book2会被release


return 0;
}

  • 典型例子(错误),以下代码会有内存泄露

评论

热度(2)