1.前言
本來以為在改成ARC以后,不再需要考慮內存問題了,可是在實踐中還是發現有一些內存問題需要注意,今天我不談block的循環引用的問題,主要說說一些對象、數組不內存得不到釋放的情況.
2.數組內存得不到釋放的情況
//組織字典數據
- (NSMutableDictionary *)setupDicData{
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (int i = 0; i <= 30; i++) {
[dict setObject:[self setupArrayData] forKey:[NSString stringWithFormat:@"%d%@",i,@"class"]];
}
return dict;
}
//組織數組數據
- (NSMutableArray *)setupArrayData{
NSMutableArray *marry = [NSMutableArray array];
for (int i = 0; i<=30; i++) {
NSString *s = [NSString stringWithFormat:@"%@",@"data-test"];
[marry addObject:s];
}
return marry;
}
運行+——
- (void)viewDidLoad {
[super viewDidLoad];
while (true) {
//30.0定時執行
[NSThread sleepForTimeInterval:30.0];
NSDictionary *dict = [self setupDicData];
NSLog(@"%@",dict);
//每次數據內存都得不到釋放
}
}
//按上代碼傳遞數組執行,每次數組、對象內存都得不到釋放。如圖:
內存會無線的往上增加,直至崩潰。
2.是什么原因導致這種內存得不到釋放的?
主要是你在iOS里使用 while (true) {} 無線循環時,
iOS ARC默認認為你這個方法永遠沒有執行完,所以不會去主動釋放你方法里的對象,這一點和JAVA不一樣,
所以很多JAVA開發者轉iOS后習慣性的使用while(true){}
導致項目里存在這種內存隱患,導致內存無限增加。
3.如何解決這種數組傳遞內存得不到釋放的情況?
解決方法一:
3.1.最簡單最直接在ARC的環境下使用 @autoreleasepool {}
//@autoreleasepool {}的作用是在每次循環一次,都會把內存主動釋放掉
- (void)viewDidLoad {
[super viewDidLoad];
while (true) {
@autoreleasepool {
//30.0定時執行
[NSThread sleepForTimeInterval:30.0];
NSDictionary *dict = [self setupDicData];
NSLog(@"%@",dict);
//每次數據內存都得不到釋放
}
}
}
內存圖,我們發現很穩定,每次都會主動將內存釋放
解決方法二:
3.2.使用NSTimer來做數組傳遞的無限循環,ARC會自動幫你釋放內存
- (void)usingDatadosomething{
//30.0定時執行
[NSThread sleepForTimeInterval:0.10];
NSDictionary *dict = [self setupDicData];
NSLog(@"%@",dict);
//每次數據內存都得不到釋放
}
- (void)viewDidLoad {
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:30.0 target:self selector:@selector(usingDatadosomething) userInfo:self repeats:YES];
[[NSRunLoop currentRunLoop] run];
}
內存圖如下

解決方法三:
3.3.使用block封裝數組傳遞,最后做block的釋放,ARC會自動幫你釋放內存
block使用較為頻繁,不在本文章闡述,下次會專門寫一篇block的博客。
謝謝大家,還有什么疑問可以評論中提出,我有時間會耐心回復!
