IOS学习第23天
内存管理的概述
1.内存中的五大区域
栈区,堆区,BSS段,数据段,代码段
堆区中的OC对象,是我们要管理内存的范围
2.什么时候释放堆区中的OC对象?
不用的时候需要释放OC对象
有用着的不能释放OC对象
3.到底怎么判断 有没有用这个OC对象
所有的OC对象中 有一个属性 叫 retainCount (类型是unsigned long,中文名字叫做引用计数器)
代表:这个对象有多少人使用
1>当对象刚刚创建的时候 retainCount = 1
可以通过点语法调用 对象.retainCount 来获取对的引用计数器值
2>如果多一个人使用 需要为retainCount 加上1 ,OC对象提供了一个方法
retain,这方法内部就是为retainCount 加上 1
3>如果正在用这个对象的人,不用了,需要为retainCount 减去1,
OC对象中也提供了一个方法,叫做release 内部就是为retainCount减去1
4>就这样++-- 如果有一天retainCount == 0,那么证明这个对象没人用了
"此时系统就会 立即 马上 rightnow 回收这个对象.
系统回收一个对象的时候,系统会调用对象的 这个方法:[对象 dealloc]
4.OC内存管理方式
MRC:程序员自己需要 控制retainCount变化
ARC:程序员自己不需要 控制retainCount变化
5.ARC和MRC的关系
1)ARC是基于MRC的,本质上是相同的,只不过是编译器帮助程序员来书写对于对象的内存管理的代码
2)ARC是在2011年ios5出现的
3)从xcode6开始创建的项目默认都是ARC的
内存管理的原则
1.有对象的创建 就要为对象匹配一个release
2.谁负责retain 对象 谁就要负责release这个对象
3.retain 的次数 和 release 次数 要保持平衡,retain一次 就要 release一次
总结:
有new或者[[alloc] init]方法 就要有一个release
有retain 也有要一个release
```
###野指针与僵尸对象
1.什么是野指针
1)C中的野指针
int main() {
//C语言中的野指针
int *p2;//申明一个指针 但是没有初始化
return 0;
}
2)OC中的野指针
一个指针 指向了一个对象,但是这个对象已经被回收
OC 中所说的回收,是指这个对象的所占的内存可以分配给别人使用
回收对象之后 对象的数据可能还是存在的,但是我们不用
2.僵尸对象
一个对象,这个对象已经被回收,但是还没有分配给别人
野指针:就是指向僵尸对象的指针
3.僵尸对象能不能使用?
僵尸对象肯定是不能用,但是xcode默认是不会报错,我们需要xcode报错
需要开启僵尸对象实时检查机制:
选中切换Target的栏–>点击Edit Scheme–>选中Diagnostics—>
Enable Zombie Objects 这样就开启僵尸对象检查机制
4.僵尸对象不能复活,不要去研究僵尸对象的一些属性(retainCount,其他属性)
5.一个对象 什么时候需要发送retain消息?
当一个对象多一个人使用的时候,需要发送retain消息
对象多一个人使用 是指这个对象 多了一个指针指向他
“`
多个对象的内存管理
1.只有属性的类型是OC对象的时候,才要在setter方法中写标准的MRC内存管理代码
2.NSString类型的属性,也要在setter方法中写标准的MRC内存管理代码
- (void)setCar:(Car *)car
{
//新旧对象不一样
if(_car != car)
{
//旧的release
[_car release];
//新的retain 同时赋值
_car = [car retain];
// //新的retain
// [car retain];
// //赋值
// _car = car;
}
}
- (void)dealloc
{
[_car release];
[super dealloc];
}
与@property相关的参数
- 与多项成相关的参数
1.与多线程相关的参数
atomic:安全 效率低 [默认值]
nonatomic:不安全 效率高,[一般都写这个]
2.其他
与生产的setter方法的实现相关: assign retain
与生产的getter和setter方法名相关的:getter setter
与读写相关: readwrite readonly
```
* 与生成setter方法实现相关的参数
1.与生成setter方法实现相关的
assign:生产的setter方法实现 直接赋值 [默认值]
retain:生产的setter方法实现 是标准的内存管理代码
2.什么时候使用assign 和 retain
当一个属性 是OC对象的时候 我们使用参数retain
当一个属性 是非OC对象的时候 我们使用参数assign
3.如果你使用了retain
只会生产settter方法实现的标准内存管理代码
但是在dealloc中,必须写上[_car release]
“`
* 与setter方法和getter方法名相关的参数
1.readonly 和 readwrite参数
readwrite:同时生产setter和getter方法
readonly:只会生产getter方法
2.getter 和 setter参数
getter = xxx,生产的getter方法 名字变成xxx
setter = xxx:,生产的setter方法 名字变成xxx:
注意:
1>无论何时何地,不要用setter = xxx:
2>只有一个情况 可以用getter,属性是BOOL类型
用getter的目的是提高可读性
```
* 使用注意
1). 与多线程相关的两个参数: 用nonatomic.
2). 与生成的setter方法实现相关的参数:
assign : 当属性的类型是非OC对象的时候.
retain : 当属性的类型是OC对象的时候.
retain只是在setter方法中生成标准的MRC内存管理代码.
并不会在dealloc中也生成release代码.
"所以,dealloc中的release还要自己去写.
3). 同1组参数只能使用1个.(除了)
4). 顺序是可以换
“`