Objective-C内存管理(下)

一.autorelease(自动释放池)

1、autorelease 的基本用法

(1) 会将对象放到一个自动释放池中
(2) 当自动释放池被销毁时,会对池子里面的所有对象做一次 release 操作

(3) 会返回对象本身
(4) 调用完 autorelease 方法后,对象的计数器不变


//写完这行代码,就不用再写【p release】;
Person *p = [[[Person alloc] init] autorelease];

注意的是,还要把它写在释放池中!

@autoreleasepool{//创建

Person *p = [[Person alloc] init] autorelease];
p.age = 19;
}//此处销毁释放池

2、autorelease 的好处
 

(1) 不用再关心对象释放的时间 

(2) 不用再关心什么时候调用 release

3、autorelease 的使用注意
 

(1) 占用内存较大的对象不要随便使用 autorelease
(2) 占用内存较小的对象使用 autorelease,没有太大影响 


4.错误用法:

//alloc 之后调用了 autorelease,又调用 release
@autoreleasepool {
Person *p = [[[Person alloc] init] autorelease];
[p release]; 
}
//(2) 连续调用多次 autorelease
@autoreleasepool
{
Person *p = [[[[Person alloc] init] autorelease] autorelease]; 
}

5、自动释放池


(1) 在 iOS 程序运行过程中,会创建无数个池子。这些池子都是以栈结构存在(先进后出)

(2) 当一个对象调用 autorelease 方法时,会将这个对象放到栈顶的释放池


6、自动释放池创建方式


(1) iOS 5.0 之前

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

[pool release]; // [pool drain];

(2) iOS 5.0 开始

@autoreleasepool {
}


注意:

1.系统自带的方法中,如果不包含 alloc、new、copy,那么这些方法返回的对象都是已经 autorelease 过的 

[NSString stringWithFormat:....];
[NSDate date];

 2.开发中经常写一些类方法快速创建一个 autorelease 的对象(创建对象的时候不要直接使用类名,用 self)

提供1个类方法来快速的得到1个对象. 规范 a. 这个类方法以类名开头. 如果没有参数就直接是类名 如果有参数就是 类名WithXX: b. 使用类方法得到的对象,要求这个对象就已经被autorelease过了.

+ (instancetype)person {

return [[[self alloc] init] autorelease];

}

 

开发小知识:

- (void)dealString {
    for (int i=0; i<10000; i++) {
        NSString *str = [NSString stringWithFormat:@"%d", i];
        NSLog(@"%@", str);
    }
}

  正常来说,我们声明的10000个局部变量str,会在方法执行结束进行释放,也就是循环结束

如果加上@autoreleasepool

- (void)dealString {
    for (int i=0; i<10000; i++) {
        
        @autoreleasepool {
            NSString *str = [NSString stringWithFormat:@"%d", i];
            NSLog(@"%@", str);
        }
        
    }
}

但如果加了自动释放池,局部变量出了自动释放池就释放了,所以局部变量是一边创建一边释放的,会避免局部内存高峰。

猜你喜欢

转载自blog.csdn.net/null959_/article/details/81154138