一、内存管理的概念:内存管理是在程序需要时,程序员分配一段内存空间,而当使用完之后将它释放。如果程序员对内存资源使用不当,有时不仅会造成内存资源浪费,甚至会导致程序crach。
二、为什么要管理内存?
1.不要释放或者覆盖还在使用的内存,这会引起程序崩溃;
2.释放不再使用的内存,防止内存泄露(内存泄露:不再使用的内存未释放)。iOS程序的内存资源是宝贵的。
(1)野指针:指针指向已经被释放的内存空间。
(2)内存泄露:不再使用的内存未释放。
(3)过度释放: 已经释放的内存再次释放。
三、内存管理机制:谁创建谁释放,谁引用(retain)谁管理(不用的时候relaease)。
内存分为5个块
(1)代码区:存放代码
(2)未初始化变量区:static 静态变量 静态变量与普通变量的区别 静态变量值初始化一次 static int a;
(3)已初始化变量区 : static int a = 0;
(4)堆区 :用alloc,new创建的对象 存放在堆区 这个区的内存手动管理
(5)栈区:非alloc,new创建的对象存放的区 系统管理内存(指针放在栈区,而指针指向的对象放在堆区)
四、怎么管理内存?
c/c++ 纯手动管理 free(),java 内存是自动管理,垃圾回收机制
oc分为2种 ARC自动引用计数(automatic reference counting) MRC(manual reference counting)手动 引用计数来管理内存。
1、局部变量:在不用的时候释放
2、全局变量(_p为例):在dealloc的方法中对它进行释放 release
- (void)dealloc{
[_p release];
[super dealloc];
}
3、加号的方法的实质:减号方法创建对象然后调用autorelease方法 把这个创建的对象的内存交给系统管理。不用进行内存管理
4、属性修饰:retain对象类型,并且会使引用计数加一 assign 非对象类型(九大基本类型 结构体 代理) copy(字符串)也会使引用计数加一
(1)对象类型的set方法重写:
- (void)setxxx:(类型)参数名{
if(_属性名!=参数名){
把原来属性指向的那块地方的对象给释放掉,然后,在把传过来的那个对象给retain一次赋给我的这个属性
[_属性名 release];
_属性名 = [参数名 retain];
// 如果是用copy来修饰的属性 的set方法 只需把此处的[p retain]改成[p copy]
注意!!在set方法里 不能self.xxx,会造成死循环。
!!self.xxx与_xx的区别 前者会调用set方法,后者不会。
}
(2)assign类型的set方法
- (void)setxxx:(类型)参数名{
_age = age;
}
5 、属性内存管理:在dealloc方法进行self.xxx = nil; self.是因为会调用set方法 将其置为nil 这样比较安全
- (void)dealloc{
self.p = nil;
[super dealloc];
}
6、其他的会使引用计数增加的情况: 4种 系统管理
(1)添加到数组 (2)模态弹出 (3)push(4) addSubview
不是自己增加的引用计数不用管,是自己造成的需管理。
NSArray *arr = @[]; 加号方法里面创建 不用手动管理
7、特殊的两个释放
(1) 计时器:在页面消失的时候将计时器废除
(2)注册通知 :在dealloc 方法里 remove………根据通知名name….来移除的