首先了解一下内存的基本概念
内存分为五大区:从上到下依次为:
栈区,堆区,BSS段,数据区,代码区
栈区:局部变量 特点:存放的地址从高到低分配,函数结束的时候或者代码块结束的时候自动回收
堆区:程序运行过程中动态分配的存储空间 存放的地址从低到高
BSS段:没有初始化的全局变量和静态变量
数据区:已经初始化的全局变量和静态变量以及字符串常量
代码区:程序编译后的代码内容
移动设备的内存有限,所以每一个app的内存是有限制的,当一个app内存使用超过20M,系统就会想app发出memory warning,然后app收到消息后会回收一些不再继续使用的内存空间,比如一些不再使用的对象和变量等
为什么要管理内存:程序启动的时候会首先加载代码区,数据区,bss段的内容,这三块地方系统启动后自动加载运行的,所以内存不需要我们管理,栈区的局部变量在函数结束和代码块结束会自动回收,也不需要我们手动管理,所以我们管理的是堆区中的 (nsobject <-实例<- 对象)内存
管理范围:管理任何继承于NSObject的对象,对其它基本数据类型无效
内存泄露:代码块结束时所有局部变量会被回收,指向对象的指针也会被回收,此时对象已经没有指针指向,但是依然存在于内存中,造成内存泄露
一.内存管理的方式
1.MRC
手动引入计数
2.ARC
自动引入计数
二.MRC模式下的内存管理
首先我们创建一个Dog类
Dog.h:
#import <Foundation/Foundation.h> @interface Dog : NSObject { int _ID; } @property (assign) int ID; @end
Dog.m
#import "Dog.h" @implementation Dog @synthesize ID = _ID; -(void)dealloc { NSLog(@"dog is death"); [super dealloc]; } @end
1.引入计数器的应用
Dog *dog = [[Dog alloc]init]; //开辟一个内存空间,指针dog指向该空间 NSLog(@"%zd",dog.retainCount); //值为1 Dog *dog1 = dog; NSLog(@"%zd",dog.retainCount); //值为1,说明在mrc模式下直接赋值dog是无效的 Dog *dog2 = [dog retain]; NSLog(@"%zd",dog.retainCount); //值为2 Dog *dog3 = [dog retain]; NSLog(@"%zd",dog.retainCount); //值为3 [dog1 release]; dog1 = nil; //防止指针错位 NSLog(@"%zd",dog.retainCount); //值为2 因为指向内存空间的少了一个dog [dog2 release]; dog2 = nil; NSLog(@"%zd",dog.retainCount); //值为1 [dog release]; dog = nil; NSLog(@"%zd",dog.retainCount); //值为0
2.内存管理分析
当引入计数器为0时,系统会自动触发析构函数来回收内存
3.内存管理-->黄金法则
对一个OC对象进行alloc,retain,copy,mutableCopy的时候需要对该对象进行release或者autoRelease操作
未来的你会感谢今天努力的自己
------Alen