面向对象7

来源:互联网 发布:嫁入豪门后的生活知乎 编辑:程序博客网 时间:2024/05/19 10:14

手动内存管理

OC可用内存回收机制有如下3种:

  • 手动引用计数和自动释放池
  • 自动引用计数(ARC——Automatic Reference Counting)
  • 自动垃圾回收
    PS: IOS只支持前两者,另外需要注意的是,OC中的内存管理机制是统计引用计数,当引用计数为0时会触发对象的dealloc方法来销毁对象,从而释放内存。

引用计数方法:

  • -retain: 将该对象的引用计数器+1
  • -release: 将该对象的引用计数器-1
  • -autorelease: 不改变对象的引用计数器的值,只是将对象添加到自动释放池中
  • retainCount: 返回该对象的引用计数的值
//接口部分忽略,自行编写,以下为实现部分@implementation MyUser- (void) setItem:(MyItem*) item{    if(_item != item)    //将_item原引用的实例计数器-1,此处主要考虑到更新值时的逻辑    [_item release]    //新实例item计数器+1    [item retain];    _item = item;    //也可用 _item = [item retain]}- (void) dealloc    //重写MyUser的dealloc方法{    //销毁MyUser实例时,将item的计数器-1,以销毁item对象    [item release];    [super dealloc];}

使用自动释放池

MyItem* productItem(){    MyItem* item = [MyItem new];  //引用计数为1    NSLog(@"函数返回之前的引用计数:%ld", item.retainCount);    //autorelease不会改变对象的引用计数,但程序执行autorelease时会将该对象添加到自动释放池中    return [item autorelease];}int main(int argh, char* argv[]){    //定义自动释放池pool    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];    //通过productItem()函数获得MyItem对象,由于productItem()函数中将对象放入了自动释放池中,所以此处返回值成功,it的计数器为1    MyItem* it = productItem();    NSLog(@"it的引用计数为:%ld", it.retainCount);    //创建一个MyUser对象病添加到自动释放池中    MyUser* user = [[[MyUser alloc] init] autorelease];    NSLog(@"%ld", user.retainCount);    [pool release];    //释放自动释放池pool}

临时对象

Foundation类中,当调用方法创建对象时,若不是以alloc、new、copy、mutableCopy开头的,系统都会默认创建自动释放的对象,这些对象会在释放自动释放池时,自动释放,被称为临时对象。

如果程序需要在事件处理结束之后依然保留临时对象:

  • 将临时对象赋值前,用retain方法使引用计数+1
  • 把临时对象赋值给retain、strong、copy修饰的属性

手动管理内存的规则总结

  • 调用release方法不是销毁对象,只是将计数-1,当对象的引用计数为0时,系统会自动调用该对象的dealloc方法来销毁该对象
  • 当自动释放池回收时,会依次调用池中每个对象的release方法来使其引用计数-1,之后若引用计数为0则销毁,若大于0则会存活下来
  • 当程序使用alloc、new。copy、mutableCopy开头的方法创建对象后,该对象的引用计数为1,当不再使用该对象时,需要调用该对象的release火autorelease方法
  • 对象的retain和release方法的调用次数应该相等
  • 对于临时对象,多想在释放自动释放池之后保留临时对象,则需要手动调用retain来增加该临时对象的引用计数,或者将该临时对象赋值给retain、strong、copy修饰的属性

自动引用计数

启用ARC,并用 -fobjc-arc 编译,系统会自动管理好内存。
@autoreleasepool{} 块中都会有ARC来自动释放

0 0