objc内存管理

一、内存管理规则

1、对于通过调用带有alloc、copy、mutableCopy、new或者create一词的方法创建的任何对象及其内存,你都拥有所有权。你负责在之后的某个时刻向该对象发送release消息来释放资源。使用类似[[Foo alloc]init...]命令创建的对象需要释放。任何使用类似[foo copy]方法创建的对象需要释放。任何和CreateFoo()类似的调用所返回的对象也需要释放。

2、对于通过不带上述词的方法调用获得的对象,你都没有所有权。这些对象可以再当前执行栈中任意调用,离开当前栈之后,这些对象就不可用了。

说明:从技术上说,对象如果之前没有被保留, 那么在下一个运行循环后会被释放。不过从遵循内存管理规则的角度考虑,你可以假定对象出了作用域后,只要没有被保留,就会被释放。

  通过其他方法调用的对象通常是“自动释放”对象,自动释放对象会在应用程序下次离开运行循环时被释放。

二、使用自动释放举例:

1、返回一个自动释放对象

-(Foo *)getFoo

{

  Foo *foo = [[Foo alloc]init];

  //对foo执行一些操作

  return [foo autorelease];

}

2、alloc/autorelease对象

-(void)someMethod

{

  Foo *foo = [[[Foo alloc]init]autorelease];

  //在这里foo仍然有效

  //在方法退出之前不会释放

  [foo dosomething];

}

三、使用自动释放可能耗尽内存

在自动释放池中留有大量对象

-(void)inflateMemoryUsage

{

  for(NSUInteger n = 0; n<100000; ++n)

  {

    //对象是自动释放的

    NSData *data = [self getBigBlockOfData];

    //对数据进行处理

    [self doStuff:data];

  }

  //在这里100000个数据对象都还有效

}

解决方法:

1、在循环中释放对象

-(void)inflateMemoryUsage

{

  for(NSUInteger n=0; n < 100000; ++n)

  {

    //保留计数是1

    NSData *data = [[NSData alloc]init];

    [self putBlobOfDataIntoData:data];

    //使用创建的对象

    //处理数据

    [self doStuff:data];

    [data release];//对象在这里被释放

  }

  //没有遗留任何东西

}

 

2、在必须使用很多自动释放对象的情况下,在循环内部创建一个自动释放池,在使用完代码中的对象后,清空自动释放池并释放对象。

-(void)inflateMemoryUsage

{

  

  for(NSUInteger n = 0; n<100000; ++n)

  {

    //对象是自动释放的

    NSData *data = [self getBigBlockOfData];

    //对数据进行处理

    [self doStuff:data];

  }

  //在这里100000个数据对象都还有效

}

解决方法:

1、在循环中释放对象

-(void)inflateMemoryUsage

{

  for(NSUInteger n=0; n < 100000; ++n)

  {

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];

    //该对象是自动释放的

    NSData *data = [self getBigBlobOfData];

    //对data进行些处理 

    [self doStuff:data];   

    [pool release];//自动释放对象在这里释放,使用drain或release

  }

  //没有遗留任何对象

}

 

自动释放池中自动释放对象被推入到可用的最高层的自动释放池,这点和嵌套栈有些类似。所以如果在一个自动释放池内创建多个池,在清空池子时只有最里面的自动释放池内的自动释放对象被释放。

posted @ 2012-11-02 21:01  gagag  阅读(1542)  评论(0编辑  收藏  举报