1. 引用计数器
用来保存当前对象有几个东西正在使用它
2. 应用计数器的作用
用来判断是否应该回收内存空间
3. 引用计数器的操作
retain +1 就是使用时对象时
release -1 谁创建谁释放
retainCount 得到计数器的值 就是统计一共retain了几次
4. 如果一个对象被释放的时候,就会有‘临终遗言’会调用delloc方法
因为delloc是继承NSObject所以在写delloc的时候的是调用[super delloc]
就是在.m中写delloc方法 如果对象被销毁他就会执行
4,oc的内存管理分类
1, 因为MRC是手动管理内存
ARC是自动管理内存
我们创建项目的时候默认是ARC的
需要把项目从ARC模式改成MAC
2,共分为
系统自动管理
栈区
手动管理
堆区
他们都是系统自动管理
bss段
数据区
代码区
5,关闭arc的方法
因为xcode一般都是默认arc的方法的但是一些公司的老程序,以及苹果的低从都是arc写的
1,首先选中项目 然后将arc改为no
6,内存管理怎么判断它是否被收回的依据呢?
从写dealloc方法,,规范
1,一定是super dealloc ,而且一定是放到最后,就是释放子类占用父类的空间
2)永远不要直接通过对象调用dealloc方法(实际上调用并不会出错)一旦对象被回收了,它占用的内存就不再可用,坚持使用会导致程序崩溃(野指针错误)为了防止调用出错,可以将“野指针”指向nil(0)。
7,内存管理的原则
1,只要还有人使用这个对象就不会被回收
你要想使用对象 ,就该引用计数器+1,
不想使用对象时 ,引用计数器-1。
2,谁创建 ,谁release,
如果通过alloc,new ,copy 创建对象必须调用release ,autorelasae的方法
3.谁创建谁release
只要对象调用retain,都必须调用release。
4,就是有始有终,有加就有减,
8,野指针(僵尸对象)
1,就是堆区的空间已经被释放了,但是还有指针指针调用它
定义指针没有被初始化
2,可以开启僵尸对象的检测模式........
也可以将对象= nil;
9,内存泄露
1,栈区对象已经被释放堆区空间还没有被释放
几个特征:
1,retain 和release 个数不一样
2,对象在使用过程中被赋值为nil,如果等于nil就是指向一个特殊的地址无效地址
3,在函数或者方法中不当的使用retain或者relase造成的问题
4,多个对象泄露的问题
在.M文件中判断传递的对象是否是原来的对象,如果不是的释放,然后retain
(void)setCar:(Car*)car{
//判断_car存放的是否是 形参对象,如果不是,则执行[_car realease];
if(_car!=car) {
[_carrelease];//先释放上一个对象,(注意第一次是向nil发送release消息)_car= [car retain];
}
10,@property的参数
1,在xcode4.4之前我们要自己现实get,set方法。
4.4之后就不用了
2,修饰@property的关键字
三类:
原子性 : atomic 对属性加锁,多线程下安全,默认值
nonatomic 不加锁, 不安全 速度快
读写性 : readwrite 生成 get set方法
readonly 只生成get方法
set 处理方法: assign 对用于基本数据类型
retain 用于对象
copy
11,@Class的使用
作用:
可以可以简单的引用一个类,但是并不会包含类的所有内容
具体使用:
在.h文件中使用@class引用这个类
在.M文件中使用#import 包含这个类的。h文件
使用@class的好处
一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,这样的效率也是可想而知的
比如,循环依赖来说
用@class就不会报错
在类中相互声明
或
一个头文件使用
#import
面试题#import和@class的区别。
作用上的区别
#import会包含引用类的所有信息(内容),包括引用类的变量和方法@class仅仅是告诉编译器有这么一个类,具体这个类里有什么信息,完全不知
效率上的区别
如果有上百个头文件都#import了同一个文件,或者这些文件依次被#import,那么一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,编译效率非常低相对来讲,使用@class方式就不会出现这种问题了
12,循环retain问题
问题:就是2个对象谁都没被谁释放掉,这时候就需要以端“松手”
解决方: 当两端互相引用时,应该一端用retain、一端用assign
13, NSSting类内存管理的问题
我也不懂
14,autorelease的使用
1,自动释放池
1)在iOS程序运行过程中,会创建无数个池子,这些池子都是以栈结构(先进后出)存在的。
(2)当一个对象调用autorelease时,会将这个对象放到位于栈顶的释放池中
2,自动释放池的创建
autoreleasepool{
代表创建自动释放池
}//代表自动释放池销毁
3,使用的好处
1,不用关心什么时候释放,什么时候release
4,autorelease基本使用的语法
1,将对象放入自动释放池中,池子会对对象自动release
5,autorelease使用注意
1,并不是放到自动释放池中就会自动释放
2.对象虽然在池外边,但是把对象放到池里 然后家加autorelease依然可以自动释放
[对象 autorelease];
4,嵌套使用
总结一下:
-------------------------------知识点细节---------------------------
-1. 内存管理的范围
* 所有的OC对象(继承自NSObject类)
2. 为什么内存管理只管理OC对象?*堆中内存不连续,无法自动释放
3. 我们如何对OC对象进行内存管理?*通过操作对象的"引用计数器"
4. 引用计数器
* 什么是引用计数器?
1> 每个OC对象都有自己的引用计数器
1> 每个OC对象都有自己的引用计数器
2> 它是一个整数(int类型,占用4个字节)
3> 从字面上,可以理解为"对象被引用的次数"
4> 也可以理解为:它表示有多少人正在用这个对象
* 引用计数器的作用?
1> 系统通过"引用计数器"来判断当前对象是否可以被释放
* 对象的"引用计数器"的操作方式1> retain, +1
2> release, -1
3> retainCount, 获取对象引用计数器的值
5. 关闭ARC的方法
* 选中项目->选中Build Settings ->选中All ->搜索 Automatic Reference Counting ->修改为No
6. dealloc方法
* 当对象即将被销毁,系统自动给对象发送一条dealloc消息
* 因此,从dealloc方法有没有被调用,就可以判断出对象是否被销毁
* 重写了dealloc方法,必须调用[super dealloc],并且放在最后面调用*不要自己直接调用dealloc方法
7. 野指针\空指针\僵尸对象
* 僵尸对象:已经被销毁的对象(不能再使用的对象)
* 野指针:指向僵尸对象(不可用内存)的指针
* 空指针:没有指向存储空间的指针(里面存的是nil,也就是0)**注意:给空指针发消息是没有任何反应的,不会