iOS- 再谈ARC里内存问题,ARC里数组、对象内存得不到释放?

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的博客。

谢谢大家,还有什么疑问可以评论中提出,我有时间会耐心回复!

作者: 清澈Saup
出处:http://www.cnblogs.com/qingche/
本文版权归作者和博客园共有,欢迎转载,但必须保留此段声明,且在文章页面明显位置给出原文连接。

时间: 2024-10-10 13:20:03

iOS- 再谈ARC里内存问题,ARC里数组、对象内存得不到释放?的相关文章

iOS 再谈Keychain钥匙串,应用间数据共享打造iOS上的全家桶

我知道没Demo看博客很痛苦,所以Demo先行:https://github.com/rayshen/GIKeychainGroupDemo 该demo里有2个工程,你先运行任何一个会存储一个值,再运行另一个会访问之前的app存储的值,并修改. 官方:https://developer.apple.com/library/ios/samplecode/GenericKeychain/Introduction/Intro.html 之前博客使用过Keychain,实现了数据删除APP后还能保存,但

Objective-C:ARC自动释放对象内存

ARC是cocoa系统帮你完成对象内存释放的引用计数机制 .h文件 1 // Person.h 2 // 01-ARC 3 // 4 // Created by ma c on 15/8/13. 5 // Copyright (c) 2015年 bjsxt. All rights reserved. 6 // 7 8 #import <Foundation/Foundation.h> 9 10 @interface Person : NSObject 11 @property(nonatomi

IOS阶段学习第20天笔记(OC中的内存管理)

IOS学习(OC语言)知识点整理 一.OC中的内存管理 1)概念:内存管理的对象为所有继承了NSObject的对象,对基本数据(如:int .float.double...)无效      OC中采用引用计数器对内存做管理,他是一个整数数据,表示对象引用的次数,每个对象分配4字节      的内存空间存放引用计数器.当一个对象的引用计数器为0时 它将被自动释放,反过来说 当使用alloc.      new .copy(mutableCopy)创建新对象时,引用计数器默认为1 2)黄金法则 当使

数组及其内存控制

作者:禅楼望月(http://www.cnblogs.com/yaoyinglong/) 静态的Java数组 Java语言是典型的静态语言,因而,数组也是静态的,即当该数组被初始化之后,该数组的长度是不可变的. java 语言的数组变量是引用类型,什么意思呢?意思就是,数组变量并不是数组本身,它只是指向堆内存中的数组对象.如: 这3个变量以及各自引用的数组在内存中的分配如图: 我们平时可以通过改变数组变量的指向,让它指向的堆内存中的其他数组对象(前提是他们的编译类型是兼容的),从表面上看起来好像

单个对象内存管理

前文我们已经说了内存管理的原则:只要出现了new alloc retain ,就一定会配对出现一个release,autorelease 那么当我一个对象被释放之后,如果我们再次调用这个对象的方法(包括这个对象的retain release方法),将会出现 野指针 错误,在xcode中具体表现为 EXC_BAD_ACCESS:访问了不可访问的内存空间,就会导致这个错误. 下面这个例子#import <Foundation/Foundation.h> int main (int argc, co

java 基础概念 -- 数组与内存控制

问题1: Java在声明数组的过程中,是怎样分配内存的? 在栈内存中 建一个数组变量,再在堆内存中 建一个 数组对象.至于详细的内存分配细节,还得看 该初始化是 数组动态初始化 还是 数组静态初始化. 问题2: Java数组的初始化方式 有哪几种? 两种:动态初始化 和 静态初始化.动态初始化 指的是 仅仅指定数组的长度,不指明每个数组的元素.  静态初始化 指的是 详细指定数组的每个元素. 问题3: Java 的基本类型数组 和 应用类型数组 之间,在初始化时的内存分配机制有什么差别? Jav

程序员的基本功之数组与内存控制

1.数组初始化 Java的数组是静态的,既数组一旦初始化之后,该数组的长度就不可变,Java的数组需要初始化才能使用 数组的初始化就是为数组对象在堆内存中分配一段数组长度的连续的内存空间,并设定初始值(注意并不是数组变量初始化,而是数组对象) 初始化的方式有两种: 1)静态初始化:程序员显示的指定每个数组元素的初始值,并由系统决定数组的长度 2)动态初始化:初始化时只指定数组的长度,由系统为数组元素分配初始值 数组变量本身是引用类型,存储在栈内存中,而数组对象存储在堆内存中 int[] arr1

[Java基础] Java对象内存结构

转载地址:http://www.importnew.com/1305.html 原文于2008年11月13日 发表, 2008年12月18日更新:这里还有一篇关于Java的Sizeof运算符的实用库的文章. 学C/C++出身的我,对Java有一点非常困惑,那就是缺乏计算对象占用内存大小的机制.而在C++中就可以通过sizeof运算符来获得基本类型以及类实例的大小.C和C++中的这个操作符对于指针运算.内存拷贝和IO操作都非常有用. Java中并没有一个类似的运算符.事实上,Java也不需要这种运

iOS开发之oc(十二)--内存管理ARC

(一)自动内存管理 --ARC 1>简单点说就是让编译器完成堆空间的引用计数的加减,自动释放,程序员不再写retain 和release等方法 2>OC的自动内存管理不同于java 的垃圾回收,而是在预处理是直接在应该保留的地方加上retain,在应该改释放的地方加上release,是直接添加代码 3>从效率上讲,ARC优于手动内存管理 2.1.1 ARC 的局限性 1>使用ARC可能因为代码的不规范,导致内存提前释放 2>导入第三方库,或者导入旧代码,这些代码不支持ARC