Objective-C

autorelease

2019-02-23  本文已影响0人  越天高

1.autorelease基本概念

Person *p = [Person new];
p = [p autorelease];
Person *p = [Person new];
p = [p autorelease];
NSLog(@"count = %lu", [p retainCount]); // 1

2.自动释放池

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // 创建自动释放池
[pool release]; // [pool drain]; 销毁自动释放池

iOS 5.0 开始

@autoreleasepool
{ //开始代表创建自动释放池

} //结束代表销毁自动释放池

3.autorelease基本使用

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

Person *p = [[[Person alloc] init] autorelease];

[autoreleasePool drain];
@autoreleasepool
{ // 创建一个自动释放池
        Person *p = [[Person new] autorelease];
} // 销毁自动释放池(会给池子中所有对象发送一条release消息)
@autoreleasepool { // 创建一个自动释放池
        Person *p = [[Person alloc] init]; // 1
        // 不用关心对象什么时候释放, 只要能够访问p的地方都可以使用p
        p = [p autorelease]; // 只要调用了autorelease, 那么就不用调用release了
        
        [p retain]; // 2
        
        [p run];
    }
@autoreleasepool {

         Person *p  =[[Person alloc] init];
         
         [p run];
         
         // 时时刻刻都关注对象什么时候被释放
         [p release];
         p = nil;
         
         // 给野指针发送消息
         [p run];

    }


1.autorelease使用注意

 @autoreleasepool {
    // 因为没有调用 autorelease 方法,所以对象没有加入到自动释放池
    Person *p = [[Person alloc] init];
    [p run];
}
 @autoreleasepool {
 }
 // 没有与之对应的自动释放池, 只有在自动释放池中调用autorelease才会放到释放池
 Person *p = [[[Person alloc] init] autorelease];
 [p run];

 // 正确写法
  @autoreleasepool {
    Person *p = [[[Person alloc] init] autorelease];
 }

 // 正确写法
 Person *p = [[Person alloc] init];
  @autoreleasepool {
    [p autorelease];
 }

   // 一个程序中可以创建N个自动释放池, 并且自动释放池还可以嵌套
    // 如果存在多个自动释放池的时候, 自动释放池是以 "栈" 的形式存储的
    // 栈的特点: 先进后出
    // 给一个对象方法发送一条autorelease消息, 永远会将对象放到栈顶的自动释放池
    
    @autoreleasepool { // 创建第一个释放池
        @autoreleasepool { // 创建第二个释放池
            @autoreleasepool { // 创建第三个释放池
                Person *p = [[[Person alloc] init] autorelease];
                p.age = 12;
                [p run];
            } // 第三个释放池销毁
            
            Person *p = [[[Person alloc] init] autorelease];
            p.age = 10;
            
        }// 第二个释放池销毁
    }// 第一个释放池销毁
// 内存暴涨
    @autoreleasepool {
        for (int i = 0; i < 99999; ++i) {
            Person *p = [[[Person alloc] init] autorelease];
        }
    }
// 内存不会暴涨
 for (int i = 0; i < 99999; ++i) {
        @autoreleasepool {
            Person *p = [[[Person alloc] init] autorelease];
        }
    }

autorelease应用场景

+ (instancetype)person
{
    return [[[self alloc] init] autorelease];
}


- (instancetype)initWithAge:(int)age{
    if (self = [super init]) {
        _age = age;
    }

    return self;
}

+ (instancetype)personWithAge:(int)age
{
    /*
    Person *p = [[self alloc] init];
    p.age = age;
    return [p autorelease];
     */
    return [[[self alloc] initWithAge:age] autorelease];
}

- (void)dealloc
{
    NSLog(@"%s", __func__);
    [super dealloc];
}
上一篇下一篇

猜你喜欢

热点阅读