黑马程序员 内存管理

干柴:

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

  • 打印的结果

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

  


3、对象所以权

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

  • 使用release、autorelease释放对象所有权


4、黄金法则

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

    

5、如何持有一个对象

  • 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 )

© 小小技术博客 | Powered by LOFTER