OC内存管理的基本概念
答:因为内存是有限的,而我们可以无限的分配内存空间,这样会造成内存泄露,所以需要内存的管理.
1. 内存分为以下几个区域. // 必考题牢记
栈区 : (局部变量) 所有代码块或函数结束的时候回收,不需要程序猿自己管理,内存分配从高到低分配
堆区 : 程序运行时,动态分配的存储空间,OC中的对象 (内存分配从低到高)
BSS段 :(没初始化的全局变量和静态变量)
数据区:(初始化的全局变量) ,程序启动的时候加载的
代码段:程序编译以后代码的内容
3.苹果程序运行流畅是因为在一个程序占用内存空间过大的时候会自动释放.
20M 提示WARNING 45M的时候提醒 120 M时候闪退
4.内存管理范围:
管理任何继承NSObject 的对象,对其他的基本数据类型无效. // 牢记
研究的内存区域是堆区,管理的是堆区的对象
5.内存管理的原理
a.对象的所有权及引用计数
对象所有权的概念:
任何对象都可能拥有一个或多个所有者,只要一个对象至少还拥有一个所有者,它就会继续存在
Person *p=[[Person alloc] init];
引用计数器:用来保存当前对象有几个对象在使用它(数字)
6.引用计数器的作用:
引用计数器是判断对象要不要回收依据(存在一种例外,对象值为nil时,引用计数器为0,但不回收空间) 就是计数器是否为0, 不为0则存在.
Person *p =nil ;
7. 对引用计数器的操作 // 重点复习
给对象发送消息,进行相应的计数器操作.
retain消息:使计数器+1,该方法返回对象本身
release消息:使计数器-1(并不代表释放对象)
retainCount 消息:获得对象当前的引用计数器值 %ld %tu
如果一个对象被释放的时候,会有临终遗言(会调用该对象的dealloc方法)
注意:1 dealloc方法是NSObject的,一般我们要重写的 dealloc方法
2.在dealloc方法的内部,要调用 [ super dealloc];
8.内存管理的分类: // ARC自动管理,和 MRC 手动管理
手动内存管理 (MRC) manual reference counting
手动管理,在开发. iOS4.1之前的版本
自动内存管理 (ARC) automatic reference counting : Xcode4.1之后推出的
垃圾回收: garbage collection IOS 不支持垃圾回收
A. [掌握] 关闭ARC的方法
(1) 设置项目信息 设置ARC 为 NO
B [掌握]手动管理(MRC)快速入门 : 重写dealloc 方法,代码规范
(1) 一定要[super dealloc ] 而且要放到最后,意思是:先释放子类占用的空间在释放父类占用的空间
(2) 对 self 当前所拥有的其他对象做一次 release 操作
注意:永远不要直接通过对象调用 dealloc 方法 (实际上调用并不会出错)
9.手动内存管理快速入门
注意:我们创建一个项目,此时默认的是ARC的(自动内存管理) 把项目从ARC 模式改成 MRC 模式
10.内存管理的原则
a. 如果对象有人使用,就不应该回收
如果你想使用这个对象,应该让这个对象 retain 一次.
如果不想使用这个 对象了,应该让这个对象 release 一次.
// 创建对象方法: new 和 alloc init 和 copy
b. 谁创建, 谁release // 重点要记住
Dog * bigYellowDog=[Dog new]; // 1
[bigYellowDog release] //只有保证谁创建谁release,才能保证对象能够释放.
c.谁 retain 谁release
内存管理研究的内容:
1,野指针 (僵尸对象) 2.定义的指针变量没有初始化 2. 指向的空间已经被释放了.
2. 内存泄露:
// P 栈区, [Person new ] 堆区
Person *p=[ Person new ]
如果栈区的p已经释放了,而堆区的空间还没有释放,堆区的空间就被泄露了.
A.单个对象内存管理
12.nil和Nil 和Null 的区别 // 面试题
nil :给对象赋值
Nil: 给类赋值
Null: 通用指针 // 空指针概念:(没有指向存储空间的指针(里面存的是nil, 也就是0 )
[NSNull null ] 是一个对象,他用在不能使用nil的场合
B.常见单个对象内存泄露问题有几个情况? // 面试题
1. 创建完成, 使用之后,没有release
2.没有遵守内存管理的原则
3.不当的使用了nil
4.在方法中对传入的对象进行了retain
C.对象之间的3种关系 : 组合, 依赖,关联 // 面试题
D.多个对象内存泄露问题
保证在p对象存在的时候,car对象一定存在,对象p被销毁的时候,car对象销毁.
_Car = [ car retain ] // 赋值为2 , release 减1,retain 加1.
E.set方法内存管理
1.基本数据类型:直接赋值
2.OC对象类型
F.set 方法存在的问题
原对象无法释放造成的内存泄露,原对象能够释放,但是引起新的问题,set自己的时候,造成野指针.
解决上诉问题: 判断新传递的对象是否是原来的对象,如果不是原来的则释放,然后再retain .
_(void)setCar:(Car *) car
{
if (car !=_car){
[ _car release] ;
_ car =[car retain];
}
}
1,
1)基本数据类型:直接赋值
intfloat double long struct enum
-(void)setAge:(int)age
{
_age=age;
}
2)OC对象类型,需要做如下判断;
-(void)setCar:(Car *)car
{
//1.先判断是不是新传进来的对象
if(car!=_car){
//2对旧对象做一次release
[ _car release];//若没有旧对象,则没有影响
//3.对新对象做一次retain
_car=[car retain];
}
} |
|