一. 内存管理概念
1,为什么要有内存管理?
一般的内存 4s 是512M内存;6是1024M内存;
当内存过大时,会耗尽内存。出现程序闪退。
2、OC内存管理的范围 :
管理任何继承NSObject的对象,对其他的基本数据类型无效。
3、对象类型是程序运行过程中动态分配的,存储在堆区;内存管理主要是对堆区中的对象的内存管理。
4、OC内存管理的原理
对对象的引用计数器(retaincount) 进行管理,当retaincount变为0的时候系统会回收内存.
5、内存管理的分类:
MRC(MannulReference Counting),手动管理;
ARC(automatic reference counting),自动引用计数管理;
//对象的销毁
当一个对象的引用计数器为0时,那么它将被销毁,其占用的内存被系统回收。
当对象被销毁时,系统会自动向对象发送一条dealloc消息,一般会重写dealloc方法,在这 里释放相关的资源,dealloc就像是对象的“临终遗言”。
一旦重写了dealloc方法就必须调用[super dealloc],并且放在代码块的最后调用(不能直 接调用dealloc方法)。
一旦对象被回收了,那么他所占据的存储空间就不再可用,坚持使用会导致程序崩溃(野指 针错误)。
6,内存管理法则
6.1,内存管理的原则(必须要遵守这个原则)
谁创建(alloc,new),谁release或者autorelease;// 谁创建,谁释放
谁retain,mutableCopy(copy),谁release或autorelease;//谁引用,谁释放
6.2、内存管理研究的内容
野指针(僵尸对象)
内存泄露
二.单个对象内存管理
1、野指针
野指针: 未初始化的指针 或者 所指向的内存已经被释放的指针。
僵尸对象: 内存被回收的对象称为僵尸对象;
(默认情况下xcode为了提高编码效率,不会时时检查僵尸对象,所以默认不打开检测僵尸对象的选项)
2、内存泄露
内存泄露 (栈区的指向已经释放, 堆区的空间没有释放, 这时堆区的空间就被泄露了)
泄露原因:
2.1对象创建了之后,没有release;
2.2retain 或 alloc 的总和大于 release或autorelease的和;
面试题:
nil和Nil及NULL、NSNull的区别:
nil: 是一个对象空值;如果我们要把一个对象设置为空的时候就用nil;
Nil :是一个类对象的空值,如果我们要把一个Class类型的对象设置为空的时候就用Nil ;
NULL 是一个c语言指针空值;
NSNull 是一个对象,它用在不能使用nil的场合;
三. 多个对象内存管理
set方法的内存管理
1)基本数据类型或者C语言的构造类型:直接赋值
int float 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];
}
}
四,@property参数(有三类共7个)
@property xcode4.4前
@property 帮我们生成get和set方法的声明
我们自己实现 get和set方法
@property 和@synthesize联合
@property xcode 4.4后
@property 增强
@property int age;
1)生成一个_age
2)生成get和set方法的声明
3)生成 get和set方法的实现
@property (......) int age;
1.读写属性
readonly:只读,只会生成getter的声明和实现
readwrite:默认的,同时生成setter和getter的声明和实现
2)(原子性)多线程管理(苹果在一定程度上屏蔽了多线程操作)
nonatomic:高性能,一般使用这个(对属性不加锁,多线程下不安全,但速度快)
atomic:低性能,默认(对属性加锁,多线程下线程安全,默认值)
3)(set方法处理)内存管理相关参数
retain: 对对象release旧值,retain新值(适用于OC对象类型)
assign: 直接赋值(默认,适用于非oc对象类型)
copy: release旧值,copy新值
//
@property(nonatomic,assign)Car *car;
@property(nonatomic,retain)Car *car;
@property(atomic,retain)Car *car;
4)set和get方法的名称
修改set和get方法的名称,主要用于布尔类型。因为返回布尔类型的方法名一般以is开头,修改名称一般用在布尔类型中的getter。
@property(nonatomic,assign, setter=isVip)BOOL vip;
@property(nonatomic,assign, setter=abc:,getter=haha)int age
//注意方法名中的冒号