黑马程序员--IOS学习笔记(Object—C)内存管理
来源:互联网 发布:建表sql语句 编辑:程序博客网 时间:2024/04/28 23:59
---------------------- <a href="http://www.itheima.com"target="blank">iOS开发</a>、期待与您交流! ----------------------
笔记总结:
一、基本原理
1. 什么是内存管理
* 移动设备的内存极其有限,每个app所能占用的内存是有限制的
* 当app所占用的内存较多时,系统会发出内存警告,这时得回收一些不需要再使用的内存空间。比如回收一些不需要使用的对象、变量等
* 管理范围:任何继承了NSObject的对象,对其他基本数据类型(int、char、float、double、struct、enum等)无效
2. 对象的基本结构
* 每个OC对象都有自己的引用计数器,是一个整数,表示“对象被引用的次数”,即有多少人正在使用这个OC对象
* 每个OC对象内部专门有4个字节的存储空间来存储引用计数器
3. 引用计数器的作用
* 当使用alloc、new或者copy创建一个新对象时,新对象的引用计数器默认就是1
* 当一个对象的引用计数器值为0时,对象占用的内存就会被系统回收。换句话说,如果对象的计数器不为0,那么在整个程序运行过程,它占用的内存就不可能被回收,除非整个程序已经退出
4. 引用计数器的操作
* 给对象发送一条retain消息,可以使引用计数器值+1(retain方法返回对象本身)
* 给对象发送一条release消息,可以使引用计数器值-1
* 可以给对象发送retainCount消息获得当前的引用计数器值
5. 对象的销毁
* 当一个对象的引用计数器值为0时,那么它将被销毁,其占用的内存被系统回收
* 当一个对象被销毁时,系统会自动向对象发送一条dealloc消息
* 一般会重写dealloc方法,在这里释放相关资源,dealloc就像对象的遗言
* 一旦重写了dealloc方法,就必须调用[super dealloc],并且放在最后面调用
* 不要直接调用dealloc方法
* 一旦对象被回收了,它占用的内存就不再可用,坚持使用会导致程序崩溃(野指针错误)
***笔记(基本理论)***
retain 返回对象本身 比如:
Person *p = [[Person alloc] init]; // retainCount为1,p是在栈内存中,其内保存着指向堆内存中开创出来的Person对象地址的值。
[p retain]; // 返回本身 亦可表示成 p = [p retain] // retainCount为2
[p release]; // 计数器减1 retainCount 为1
[p release]; // 计数器再减1retainCount 为0 ,将自动调用person对象的 dealloc方法,释放内存。注意,此时,p 中仍然保存着person对象的地址值,但此时,联系已经断开了,堆内存中的person对象已经消除了,称为僵尸对象!p此时也称为野指针!
p.age = 5; // 注意,此处等于调用僵尸对象赋值,可能会不报错。在Xcode中开启内存管理开关(僵尸对象检查机制),就会报错。打开方法:Editschema --> Diagnostics -->Objective-c Enable Zombie Objects 上打钩
[p release]; // 此时会报错。野指针指向的僵尸对象没法release;
p = nil; // 将 p 这个野指针清空,此时称为 空指针
[p release]; // 此处无错,空指针指向空对象可以release二、set方法内存管理
如果你有个OC对象类型的成员变量,就必须管理这个成员变量的内存。比如有个Book *_book
1. set方法的实现
- (void)setBook:(Book *)book{
if (book !=_book) {
[_bookrelease];
_book= [book retain];
}
}
2. dealloc 方法的实现- (void)dealloc {
[_book release];
[super dealloc];
}
三、@property参数1. 控制set方法的内存管理
* retain: release旧值,retain新值(用于OC对象)
* assign : 直接赋值,不做任何内存管理(默认,用于非OC对象类型)
* copy : release旧值,copy新值(一般用于NSString *)
2. 控制需不需生成set方法
* readwrite :同时生成set方法和get方法(默认)
* readonly :只会生成get方法
3. 多线程管理
* nonatomic 非多线程 性能高
* atomic 多线程 性能低 注意,默认是atomic的
示例:
@property(nonatomic,retain) NSString * name;
@property(nonatomic,assign) int age;
四、循环引用问题
即:A类中有一个属性是B对象,B类中有一个属性是A对象。这种情况在使用过程中,是会报错的。解决方法如下:
在一个类中用assign声明属性,另一个类中用retain声明属性即可
额外说明:在.h文件中,用 @class 方式声明一个欲使用的类,在.m文件中再用#import引用类 (如有用到该类方法需导入此类时)五、autorelease
* 给某个对象发送一条autorelease消息时,就会将这个对象加到一个自动释放池中
* 当自动释放池销毁时,会给池子里面的所有对象发送一条release消息
* 调用autorelease方法时并不会改变对象的计数器,并且会返回对象本身
* autorelease实际上只是把对release的调用延迟了,对于每一次autorelease,系统只是把该对象放入了当前的autoreleasepool中,当该pool被释放时,该pool中的所有对象会被调用Release
使用了autorelease,就不必再顾虑对象在何处release了,对象会被扔到自动释放池里,工作完了会自动release池子里的对象。autorelease返回对象本身。
注意:
1> 使用了autorelease,对象的引用计数并不会变化。
2> 占用内存较大的对象,不要随便使用autorelease,因为他会一直占用着内存,等待自动释放池销毁。反之,占用内存较小的对象,使用autorelease则没有多大影响。3> autorelease错误写法1:
@autorelease{
Person *p = [[[Person alloc] init] autorelease]; // 计数器为 1
[p release]; // 计数器为0 此时p为野指针
} // 自动释放池在此行销毁,会再次release一次其内的对象,也即再一次[prelease],而此时p是野指针了,所以会报错
错误写法2:
@autorelease{
Person *p =[[[[Person alloc] init] autorelease]autorelease];
}// 连续多次调用autorelease等效于自动释放池一销毁,会多次调用release,会引发野指针调用错误。
autorelease实用技巧:
若每次创建对象,都如此这般 Person * p = [[[Person alloc] init] autorelease]; 会显得很繁琐,尤其是多次创建对象。此时,可以在类中建立一个静态方法,示例如下:
+(id) person{ return [[[self alloc] init ] autorelease]; }
这样,每次创建对象的时候,只要 Person * p = [Person person];即可。
注意,这里用self而不是Person是有讲究的,原因是考虑到Person的子类情况。例如,GoodPerson继承 Person类,如果此处不用self,而用Person,那么GoodPerson *gp = [GoodPerson person];实际返回的还是Person对象,这样子类中的一些方法就无法使用了。
六、ARCARC的判断准则:只要没有强指针指向对象,就会释放对象。
指针分两种:
1> 强指针,默认情况下,所有指针都是强指针 __strong
2> 弱指针,__weak 使用示例:
__weak Person * p = [[Personalloc] init];
手动管理内存到ARC的等效转变
@propery(nonatomic,retain) ----->@property(nonatomic,strong) 适用于OC对象---------------------- <a href="http://www.itheima.com"target="blank">iOS开发</a>、期待与您交流! ----------------------
- 黑马程序员--IOS学习笔记(Object—C)内存管理
- 黑马程序员——IOS学习笔记(Object-c基础)
- 黑马程序员——ios学习笔记 OC 内存管理
- 黑马程序员——IOS学习笔记(MRC内存管理)
- 黑马程序员——Object-C基础(九)内存管理
- 黑马程序员- IOS学习笔记-OC内存管理学习
- 黑马程序员——Objective-C程序设计(第4版)学习笔记之17-内存管理和自动引用计数——黑马 IOS 技术博客
- 黑马程序员-IOS学习笔记 OC 内存管理
- 从今天开始学习ios,入门第二天(Object-C学习笔记)内存管理
- 黑马程序员-IOS开发之--Object-c-- 内存管理一
- 黑马程序员-IOS开发之--Object-c-- 内存管理二
- ios学习--Object-C中的内存管理
- 黑马程序员————IOS学习笔记 第8篇 内存管理优化
- Object-C学习笔记十-----内存管理
- object-c 内存管理学习笔记
- Object C学习笔记4-内存管理
- Object C学习笔记4-内存管理
- 黑马程序员-Object C之set方法的内存管理
- Android广播接实现电话的监听(电话的状态,拦截)
- 编程算法之枚举法续(马载粮食)
- 《Orange'S:一个操作系统的实现》学习笔记(四)
- 搭建高可用mongodb集群(三)—— 深入副本集内部机制
- Cocos2d-3.x_加载网页(Android和iOS平台)
- 黑马程序员--IOS学习笔记(Object—C)内存管理
- 一元多项式的加法和乘法
- Java 编程下线程的生命周期
- map容器
- hashcode与字符串
- vijos 1514 RMQ
- Traning@4.11 div2
- 分析Linux内核创建一个新进程的过程
- 添加子VIewcontroller