OC基础-内存管理-引用计数器+set方法
2014-09-30 18:52
267 查看
<1>内存管理--引用计数器
1. 内存中分为五大区域,其中两个是栈和堆。栈存放局部变量,堆存放对象等动态产生的变量,当变量的作用域失效后,栈里的变量系统自动回收,堆不是。
2. 每个对象内部都有自己的引用计数器:表示有多少人在用这个对象(引用器占4个字节)。对象被创建的时候计数器默认是1,当计数器减为0时,对象被回收,只要不是0就不会被回收,除非整个程序退出。
3. 操作对象的计数器
1> 当使用alloc,new或者copy创建一个对象时,计数器默认是1
(都是对象方法)
2> 给对象发送一条retain消息,可以使引用计数器值+1,retain方法返回对象本身
3> 给对象发送一条release消息,可以使引用计数器值-1
4> 给对象发送一条retainCount消息,返回当前的引用器值
4. 当对象的引用计数器为0即对象需要被销毁时,系统会自动向对象发送一条dealloc消息(对象的遗言,这比喻。。。。。) ,有时候我们会想在对象被回收之前做一些事情,所以一般都会重写dealloc方法,在这里面释放一些其它的相关资源
5. 对象有没有被回收的依据是系统有没有调用dealloc方法,所以通过重写dealloc就可以检测对象是否被回收
6. 调用dealloc方法一定要调用回super的dealloc:[super dealloc](而且一定要放到最后)
7. 被系统回收的对象是不可再用的,称之为“僵尸对象”,指向僵尸对象(不可用内存)的指针叫做“野指针”(所以不能反复多次’无限‘的release,否则会出现的错误:EXC_BAD_ACCESS(访问一块坏内存,不可用的对象/内存)这叫野指针错误。所以当指针变成野指针时要把这个指针变成空指针:p=nil; 给空指针发送消息不会报错,但是要注意的是-OC里没有空指针操作)
8. retain是有返回值的:对象本身(地址/指针),release没有返回值
<2>内存管理--set方法(涉及到多对象时)
1. 谁创建,谁release,如果你通过alloc,new或者[mutable]copy创建一个对象,那么你就必须要调用release或者autorelease,不是你创建的你就不要管
2. 谁retain,谁release。只要你调用了retain,无论这个对象是如何产生的,你都要调用release
3. 重写!重写!重写!重写方法!----好处多多
4. 总结
1> 你想使用(占用)某个对象,就应该让该对象的计数器+1(让该对象做一次retain操作)
2> 你不想再使用(占用)某个对象,就应该让该对象的计数器-1(让该对象做一次release操作)
3> 谁retain谁release,谁alloc谁release
<3>内存管理--set方法-2(用新对象代替旧对象时,就好比是一个人原来有辆250码的车(旧对象),然后要换一辆3000码的车(新对象))
1. 旧对象与新对象不是同一个对象时:当一个对象换了当前它所使用的对象的时候,就要让 被使用的旧对象release一次。方法是在set方法中让旧对象release(就是在换对象的时候让被换掉的旧对象release一次,被使用的新对象retain一次)
2. 旧对象与新对象是同一个对象时:上面的逻辑就会出现问题,因为换对象的时候,set方法都要release旧对象,但是如果被传入的‘新’对象和‘旧’对象是同一个对象时,‘旧’对象一release,它就可能已经被系统回收了,这时再对‘新’对象进行retain就是非法的. 所以我们在换对象的时候,先要if判断一下:旧对象跟新对象一样就不执行(不换),不一样才会执行(换)
3. 总结:
<1. 只要调用alloc,就必须有release(或者autorelease)
<2. set方法的代码规范
1> 基本数据类型:直接赋值
- (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];
}
}
<3. dealloc方法的代码规范
1> 一定要[super dealloc],而且要放到最后
2> 对self(当前)所拥有的其他对象做一次release
- (void)dealloc
{
[_car release];
[super dealloc];
}
4. 不管对象是怎么产生的,只要没有使用alloc,就不能用release(如NSString *的对象)
5. 这种情况,release的顺序也有要求,所以很烦,很不合理不友好。
1. 内存中分为五大区域,其中两个是栈和堆。栈存放局部变量,堆存放对象等动态产生的变量,当变量的作用域失效后,栈里的变量系统自动回收,堆不是。
2. 每个对象内部都有自己的引用计数器:表示有多少人在用这个对象(引用器占4个字节)。对象被创建的时候计数器默认是1,当计数器减为0时,对象被回收,只要不是0就不会被回收,除非整个程序退出。
3. 操作对象的计数器
1> 当使用alloc,new或者copy创建一个对象时,计数器默认是1
(都是对象方法)
2> 给对象发送一条retain消息,可以使引用计数器值+1,retain方法返回对象本身
3> 给对象发送一条release消息,可以使引用计数器值-1
4> 给对象发送一条retainCount消息,返回当前的引用器值
4. 当对象的引用计数器为0即对象需要被销毁时,系统会自动向对象发送一条dealloc消息(对象的遗言,这比喻。。。。。) ,有时候我们会想在对象被回收之前做一些事情,所以一般都会重写dealloc方法,在这里面释放一些其它的相关资源
5. 对象有没有被回收的依据是系统有没有调用dealloc方法,所以通过重写dealloc就可以检测对象是否被回收
6. 调用dealloc方法一定要调用回super的dealloc:[super dealloc](而且一定要放到最后)
7. 被系统回收的对象是不可再用的,称之为“僵尸对象”,指向僵尸对象(不可用内存)的指针叫做“野指针”(所以不能反复多次’无限‘的release,否则会出现的错误:EXC_BAD_ACCESS(访问一块坏内存,不可用的对象/内存)这叫野指针错误。所以当指针变成野指针时要把这个指针变成空指针:p=nil; 给空指针发送消息不会报错,但是要注意的是-OC里没有空指针操作)
8. retain是有返回值的:对象本身(地址/指针),release没有返回值
<2>内存管理--set方法(涉及到多对象时)
1. 谁创建,谁release,如果你通过alloc,new或者[mutable]copy创建一个对象,那么你就必须要调用release或者autorelease,不是你创建的你就不要管
2. 谁retain,谁release。只要你调用了retain,无论这个对象是如何产生的,你都要调用release
3. 重写!重写!重写!重写方法!----好处多多
4. 总结
1> 你想使用(占用)某个对象,就应该让该对象的计数器+1(让该对象做一次retain操作)
2> 你不想再使用(占用)某个对象,就应该让该对象的计数器-1(让该对象做一次release操作)
3> 谁retain谁release,谁alloc谁release
<3>内存管理--set方法-2(用新对象代替旧对象时,就好比是一个人原来有辆250码的车(旧对象),然后要换一辆3000码的车(新对象))
1. 旧对象与新对象不是同一个对象时:当一个对象换了当前它所使用的对象的时候,就要让 被使用的旧对象release一次。方法是在set方法中让旧对象release(就是在换对象的时候让被换掉的旧对象release一次,被使用的新对象retain一次)
2. 旧对象与新对象是同一个对象时:上面的逻辑就会出现问题,因为换对象的时候,set方法都要release旧对象,但是如果被传入的‘新’对象和‘旧’对象是同一个对象时,‘旧’对象一release,它就可能已经被系统回收了,这时再对‘新’对象进行retain就是非法的. 所以我们在换对象的时候,先要if判断一下:旧对象跟新对象一样就不执行(不换),不一样才会执行(换)
3. 总结:
<1. 只要调用alloc,就必须有release(或者autorelease)
<2. set方法的代码规范
1> 基本数据类型:直接赋值
- (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];
}
}
<3. dealloc方法的代码规范
1> 一定要[super dealloc],而且要放到最后
2> 对self(当前)所拥有的其他对象做一次release
- (void)dealloc
{
[_car release];
[super dealloc];
}
4. 不管对象是怎么产生的,只要没有使用alloc,就不能用release(如NSString *的对象)
5. 这种情况,release的顺序也有要求,所以很烦,很不合理不友好。
相关文章推荐
- 黑马程序员——OC基础---内存管理(引用计数器,多对象内存管理,set方法的内存管理,模型设计,循环引用)
- OC_语法入门_day5_内存管理_计数器/set方法/property的参数/循环引用/自动释放池
- 黑马程序员——IOS基础——OC内存管理-set方法内存管理及微博模型设计
- OC基础—内存管理之set方法内存管理
- OC基础—内存管理之引用计数器
- Objective-C—引用计数器、多个对象之间的内存管理、set方法的内存管理、@property参数、循环引用
- OC基础—————类型的可见度,封装,自定义方法, set 和 get
- 小白学开发(iOS)OC_ set方法的内存管理分析(2015-08-04)
- 黑马程序员-内存管理之set方法内存管理, property参数,循环引用。
- iOS开发OC基础:OC集合NSSet、NSMutableSet以及NSCountedSet的基本方法的使用
- OC基础15:内存管理和自动引用计数
- oc基础-set和get方法的使用
- 内存管理一道数组存储例题存储精讲! (oc手动管理内存,引用计数器)
- 黑马程序员——OC基础:内存管理和自动引用计数(ARC)
- OC基础—内存管理之@property及其参数(补充新知识:循环引用和@class)
- OC之set方法内存管理
- OC-内存管理-基本原理与引用计数器
- OC语法6——内存管理之引用计数器(retain,release)
- 黑马程序员——OC——set方法内存管理和property
- ObjectC语言基础3—内存管理、引用计数器、@property、模型