自动释放池 autorelease
1.自动释放池原理
1>所有 autorelease的对象,在出了作用域之后,会被添加到 最近 创建的自动释放池中
2>当自动释放池被耗尽或者销毁时,会向池中的队形发送 release 消息,释放池中的所有对象
2.重点注意问题
1>自动释放池在ARC中有用么?
自动释放池在ARC中同样有效,ARC只是在编译的时候,编译器根据代码结构添加 retain/release/autotrelease 本质上的内存管理还是程序负责
2>自动释放池是什么时候创建和销毁的?
one:在运行循环开始的时候创建
two:在运行循环结束前销毁
3.自动释放池原理示意图

4.自动释放池经典题
// largeNumber 表示一个很大很大的数
long largeNumber=10000*10000;
-(void)question
{
//问题:以下代码有什么问题?如果有?如何解决?有几种解决方式?请简述各种方式的优缺点及效率
for (int i = 0; i < largeNumber; i++) {
NSString *str = [NSString stringWithFormat:@"Hello - %04d", i];
str = [str stringByAppendingString:@" - World"];
str = [str uppercaseString];
NSLog(@"%@", str);
}
/*
注意:stringWithFormat是NSString的类方法,在 Foundation 框架中,如果是返回对象的类方法,autorelease对象都是自动释放的,因此存在问题
答案:
1.有问题,问题是:每一个str都是自动释放的,如果循环次数很大,会占用过多的自动释放池空间,甚至使自动释放池耗尽
2.解决方法使用自动释放池
1>在for循环外面使用自动释放池 见 solve1
结果:在for循环以后,倾倒自动释放池
2>在for循环内使用自动释放池 solve2
结果:内存非常的平缓
3.哪一种解决方案执行效率快
基本上一样快,亲测
注意:实际开发中应该改毫不犹豫的使用自动释放池
*/
}
/**
* 解决方式1,在for外部加上自动释放池
*/
-(void) solve1
{
NSLog(@"开始");
@autoreleasepool {
for (int i = 0; i < largeNumber; i++) {
NSString *str = [NSString stringWithFormat:@"Hello - %04d", i];
str = [str stringByAppendingString:@" - World"];
str = [str uppercaseString];
}
}
NSLog(@"解决方式1,在for外部加上自动释放池");
}
/**
* 解决方式2,在for内部加上自动释放池
*/
-(void) solve2
{
NSLog(@"开始");
for (int i = 0; i < largeNumber; i++) {
@autoreleasepool {
NSString *str = [NSString stringWithFormat:@"Hello - %04d", i];
str = [str stringByAppendingString:@" - World"];
str = [str uppercaseString];
}
}
NSLog(@"解决方式2,在for内部加上自动释放池");
}
/**
* 判断两种解决方式种方式执行时间
*/
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//判断两种解决方式种方式执行时间
CFAbsoluteTime start=CFAbsoluteTimeGetCurrent();
CFAbsoluteTime end=CFAbsoluteTimeGetCurrent();
start=CFAbsoluteTimeGetCurrent();
[self solve1];
end=CFAbsoluteTimeGetCurrent();
NSLog(@"%f",end-start);
start=CFAbsoluteTimeGetCurrent();
[self solve2];
end=CFAbsoluteTimeGetCurrent();
NSLog(@"%f",end-start);
//基本上一样快,亲测
}
@end
1.自动释放池原理
1>所有 autorelease的对象,在出了作用域之后,会被添加到 最近 创建的自动释放池中
2>当自动释放池被耗尽或者销毁时,会向池中的队形发送 release 消息,释放池中的所有对象
2.重点注意问题
1>自动释放池在ARC中有用么?
自动释放池在ARC中同样有效,ARC只是在编译的时候,编译器根据代码结构添加 retain/release/autotrelease 本质上的内存管理还是程序负责
2>自动释放池是什么时候创建和销毁的?
one:在运行循环开始的时候创建
two:在运行循环结束前销毁
3.自动释放池原理示意图
4.自动释放池经典题
// largeNumber 表示一个很大很大的数
long largeNumber=10000*10000;
-(void)question
{
//问题:以下代码有什么问题?如果有?如何解决?有几种解决方式?请简述各种方式的优缺点及效率
for (int i = 0; i < largeNumber; i++) {
NSString *str = [NSString stringWithFormat:@"Hello - %04d", i];
str = [str stringByAppendingString:@" - World"];
str = [str uppercaseString];
NSLog(@"%@", str);
}
/*
注意:stringWithFormat是NSString的类方法,在 Foundation 框架中,如果是返回对象的类方法,autorelease对象都是自动释放的,因此存在问题
答案:
1.有问题,问题是:每一个str都是自动释放的,如果循环次数很大,会占用过多的自动释放池空间,甚至使自动释放池耗尽
2.解决方法使用自动释放池
1>在for循环外面使用自动释放池 见 solve1
结果:在for循环以后,倾倒自动释放池
2>在for循环内使用自动释放池 solve2
结果:内存非常的平缓
3.哪一种解决方案执行效率快
基本上一样快,亲测
注意:实际开发中应该改毫不犹豫的使用自动释放池
*/
}
/**
* 解决方式1,在for外部加上自动释放池
*/
-(void) solve1
{
NSLog(@"开始");
@autoreleasepool {
for (int i = 0; i < largeNumber; i++) {
NSString *str = [NSString stringWithFormat:@"Hello - %04d", i];
str = [str stringByAppendingString:@" - World"];
str = [str uppercaseString];
}
}
NSLog(@"解决方式1,在for外部加上自动释放池");
}
/**
* 解决方式2,在for内部加上自动释放池
*/
-(void) solve2
{
NSLog(@"开始");
for (int i = 0; i < largeNumber; i++) {
@autoreleasepool {
NSString *str = [NSString stringWithFormat:@"Hello - %04d", i];
str = [str stringByAppendingString:@" - World"];
str = [str uppercaseString];
}
}
NSLog(@"解决方式2,在for内部加上自动释放池");
}
/**
* 判断两种解决方式种方式执行时间
*/
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//判断两种解决方式种方式执行时间
CFAbsoluteTime start=CFAbsoluteTimeGetCurrent();
CFAbsoluteTime end=CFAbsoluteTimeGetCurrent();
start=CFAbsoluteTimeGetCurrent();
[self solve1];
end=CFAbsoluteTimeGetCurrent();
NSLog(@"%f",end-start);
start=CFAbsoluteTimeGetCurrent();
[self solve2];
end=CFAbsoluteTimeGetCurrent();
NSLog(@"%f",end-start);
//基本上一样快,亲测
}
@end