- 不要等到明天,明天太遙遠,今天就行動。
須讀:看完該文章你能做什么?
知道對象什么時候才會加到autoreleasepool里面,
在autoreleasepool什么時候才釋放對象,
如何處理比較占用內存的對象
學習前:你必須會什么?(在這里我已經默認你具備C語言的基礎了)
什么是autoreleasepool
一、本章筆記
項目1
1.一定要在自動釋放池中 調用 autorelease,才會將對象方法自動釋放池中
2. 在自動釋放池中創建了對象,移動要調用 autorelease,才會將對象放到自動釋放池中
3.只要在自動釋放池中 調用 autorelease, 就會將對象放入自動釋放池中
4.一個程序中 可以創建N個自動釋放池, 并且自動釋放池 還可以嵌套
如果存在多個自動釋放池的時候,自動釋放池 是以 "棧"的形式存儲的
棧的特點: 先進后出
項目2
1.不要在自動釋放池 使用比較消耗內存的對象,占用內存比較大的對象
2.盡量不要在自動釋放池使用循環, 特別是循環的次數非常多,并且非常占用內存
二、項目1
main.m
#pragma mark 02-自動釋放池注意事項
#pragma mark 概念
/*
注意點:
1.一定要在自動釋放池中 調用 autorelease,才會將對象方法自動釋放池中
2. 在自動釋放池中創建了對象,移動要調用 autorelease,才會將對象放到自動釋放池中
3.只要在自動釋放池中 調用 autorelease, 就會將對象放入自動釋放池中
4.一個程序中 可以創建N個自動釋放池, 并且自動釋放池 還可以嵌套
如果存在多個自動釋放池的時候,自動釋放池 是以 "棧"的形式存儲的
棧的特點: 先進后出
*/
#pragma mark - 代碼
#import <Foundation/Foundation.h>
#pragma mark 類
#import "Person.h"
#pragma mark - main函數
int main(int argc, const char * argv[])
{
/*
Person *p = [[Person alloc]init];
@autoreleasepool {
// Person *p = [[Person alloc]init];
// [p run];
// 2. 在自動釋放池中創建了對象,移動要調用 autorelease,才會將對象放到自動釋放池中
// Person *p = [[[Person alloc]init]autorelease];
// [p run];
// 3.只要在自動釋放池中 調用 autorelease, 就會將對象放入自動釋放池中
p = [p autorelease];
[p run];
}
// 1.一定要在自動釋放池中 調用 autorelease,才會將對象方法自動釋放池中
// Person *p = [[Person new]autorelease];
*/
// 4.一個程序中 可以創建N個自動釋放池, 并且自動釋放池 還可以嵌套
// 如果存在多個自動釋放池的時候,自動釋放池 是以 "棧"的形式存儲的
// 棧的特點: 先進后出
// 給一個對象方法 一條autorelease消息,永遠會將對象 放到棧頂的自動釋放池
@autoreleasepool { // 創建第一個釋放池
@autoreleasepool { // 創建第一個釋放池
@autoreleasepool { // 創建第一個釋放池
Person *p = [[[Person alloc]init]autorelease];
[p run];
}// 第三個 釋放池 銷毀
}// 第二個 釋放池 銷毀
}// 第一個 釋放池 銷毀
return 0;
}
Person
>>>.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
- (void)run;
@end
>>>.m
#import "Person.h"
@implementation Person
- (void)run
{
NSLog(@"%s",__func__);
}
- (void)dealloc
{
NSLog(@"%s",__func__);
[super dealloc];
}
@end
三、項目2(02-自動釋放池大對象問題)
ViewController.m
#import "ViewController.h"
#import "Person.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
/*
// 1.不要在自動釋放池 使用比較消耗內存的對象,占用內存比較大的對象
@autoreleasepool {
Person *p = [[[Person alloc]init]autorelease];
// 加入p對象 只在100行的地方使用,以后都不用了
// 一萬行代碼
}
*/
#warning 比較消耗內存的做法
// 2.盡量不要在自動釋放池使用循環, 特別是循環的次數非常多,并且非常占用內存
@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];
// 執行到這一行,自動釋放池 就釋放了
}
}
*/
NSLog(@"----");
}
@end
棧的分析圖
image.png