内存管理

引用计数

OC是通过控制对象的引用计数来管理内存的。

内存管理原则:谁申请,谁释放

alloc / new / copy / mutableCopy 初始化对象并持有该对象,除此之外的初始化方法都不会持有该对象
retain 引用计数 +1,持有对象
release 引用计数 -1,释放对象
dealloc 当引用计数=0时,调用dealloc方法,销毁对象

初始化对象,并持有该对象:
NSString *str = [[NSString alloc]init];

初始化对象,但不持有该对象:
id obj = [NSMutableArray array];
自己持有该对象
[obj retain];

autorelease

对象调用autorelease的方法:
1.生成并持有NSAutoreleasePool对象
2.将对象添加到NSAutoreleasePool中
3.废弃NSAutoreleasePool对象

所有添加到NSAutoreleasePool中的对象,在NSAutoreleasePool废弃时都会调用release方法

内存管理_第1张图片
屏幕快照 2017-02-20 下午5.21.14.png

NSAutoreleasePool是在主线程的NSRunLoop中操作的,当调用大量的autorelease方法时,只要不废弃NSAutoreleasePool,调用autorelease的对象也不会释放,会产生内存不足的现象。
因此要在适当的地方持有并废弃NSAutoreleasePool对象

autorelease实现

GNUstep是Cocoa的互换框架,虽然源代码不相同,但实现的方式是相似的。理解GNUstep框架有助于理解苹果的源代码。

GNUstep

autorelease方法的本质是调用NSAutoreleasePool对象的addObject方法。

+ (void) addObject: (id) anObj
{
    // pool变量取得正在使用的NSAutoreleasePool
    NSAutoreleasePool *pool = 取得正在使用的NSAutoreleasePool对象;
    if( pool != nil ){
      //调用NSAutoreleasePool的对象addObject的实例方法
        [pool addObject:anObj];
    }else{
        NSLog(@"NSAutoreleasePool对象非存在状态下调用autorelease");
   }
}

addObject实例方法
当调用autorelease方法时,该对象就会被添加到NSAutoreleasePool中的数组中。

- (void) addObject: (id) anObj
{
      [array addObject: anObj];
}

通过drain废弃NSAutoreleasePool

    [pool drain];

废弃drain的过程

内存管理_第2张图片
屏幕快照 2017-02-20 下午6.07.54.png

苹果的实现

内存管理_第3张图片
屏幕快照 2017-02-20 下午6.10.55.png

内存管理_第4张图片
屏幕快照 2017-02-20 下午6.11.13.png

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