黑马程序员-OC笔记(五)内存管理
来源:互联网 发布:合昏尚知时的下半句 编辑:程序博客网 时间:2024/06/07 08:09
一、 计数器
引用计数器的基本操
引用计数器的作用
当使用alloc、new或者copy创建一个新对象时,新对象的引用计数器默认就是1
当一个对象的引用计数器值为0时,对象占用的内存就会被系统回收。换句话说,如果对象的计数器不为0,那么在整个程序运行过程,它占用的内存就不可能被回收,除非整个程序已经退出
1.方法的基本使用
1> retain :计数器+1,会返回对象本身
2> release :计数器-1,没有返回值
3> retainCount :获取当前的计数器
4> dealloc
* 当一个对象要被回收的时候,就会调用
* 一定要调用[super dealloc],这句调用要放在最后面
2.概念
1> 僵尸对象:所占用内存已经被回收的对象,僵尸对象不能再使用
2> 野指针:指向僵尸对象(不可用内存)的指针,给野指针发送消息会报错(EXC_BAD_ACCESS)
3> 空指针:没有指向任何东西的指针(存储的东西是nil、NULL、0),给空指针发送消息不会报错
二、 内存管理原则
多个对象之间的内存管理
1.你想使用(占用)某个对象,就应该让对象的计数器+1(让对象做一次retain操作)
2.你不想再使用(占用)某个对象,就应该让对象的计数器-1(让对象做一次release)
3.谁retain,谁release
4.谁alloc,谁release
三、 set 方法的内存管理
如果你有个OC对象类型的成员变量,就必须管理这个成员变量的内存。比如有个Book *_book
1. set方法的实现
- (void)setBook:(Book *)book{
if(book != _book) {
[_book release];
_book = [book retain];
}
}
2. dealloc方法的实现
- (void)dealloc {
[_book release];
[superdealloc];
}
四、@property参数
1.set方法内存管理相关的参数
* retain : release旧值,retain新值(适用于OC对象类型)
* assign : 直接赋值(默认,适用于非OC对象类型)
* copy : release旧值,copy新值(一般用于NSString *)
2.是否要生成set方法
* readwrite : 同时生成setter和getter的声明、实现(默认)
* readonly : 只会生成getter的声明、实现
3.多线程管理
* nonatomic : 性能高(一般就用这个)
* atomic : 性能低(默认)
4.setter和getter方法的名称
* setter : 决定了set方法的名称,一定要有个冒号:
* getter : 决定了get方法的名称(一般用在BOOL类型)
五 、循环引用
1.@class
的作用:仅仅告诉编译器,某个名称是一个类
@class Person; // 仅仅告诉编译器,Person是一个类
#import的区别
#import方式会包含被引用类的所有信息,包括被引用类的变量和方法;@class方式只是告诉编译器在A.h文件中B *b 只是类的声明,具体这个类里有什么信息,这里不需要知道,等实现文件中真正要用到时,才会真正去查看B类中信息
如果有上百个头文件都#import了同一个文件,或者这些文件依次被#improt,那么一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,这样的效率也是可想而知的,而相对来讲,使用@class方式就不会出现这种问题了
在.m实现文件中,如果需要引用到被引用类的实体变量或者方法时,还需要使用#import方式引入被引用类
开发中引用一个类的规范
1> 在.h文件中用@class来声明类
2> 在.m文件中用#import来包含类的所有东西
2 循环retain
比如A对象retain了B对象,B对象retain了A对象
这样会导致A对象和B对象永远无法释放
两端循环引用解决方案
1> 一端用retain
2> 一端用assign
六 、自动释放池
1.autorelease的基本用法
1> 会将对象放到一个自动释放池中
2> 当自动释放池被销毁时,会对池子里面的所有对象做一次release操作
3> 会返回对象本身
4> 调用完autorelease方法后,对象的计数器不变
2.autorelease的好处
1> 不用再关心对象释放的时间
2> 不用再关心什么时候调用release
3.autorelease的使用注意
1> 占用内存较大的对象不要随便使用autorelease
2> 占用内存较小的对象使用autorelease,没有太大影响
4.错误写法
1> alloc之后调用了autorelease,又调用release
@autoreleasepool
{
// 1
Person *p = [[[Person alloc] init] autorelease];
// 0
[p release];
}
2> 连续调用多次autorelease
@autoreleasepool
{
Person *p = [[[[Person alloc] init] autorelease] autorelease];
}
5.自动释放池
1> 在iOS程序运行过程中,会创建无数个池子。这些池子都是以栈结构存在(先进后出)
2> 当一个对象调用autorelease方法时,会将这个对象放到栈顶的释放池
6.自动释放池的创建方式
1> iOS 5.0前
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[pool release]; // [pool drain];
2> iOS 5.0 开始
@autoreleasepool
{
}
7 autoreleasepool 的 应用
1.系统自带的方法里面没有包含alloc、new、copy,说明返回的对象都是autorelease的
2.开发中经常会提供一些类方法,快速创建一个已经autorelease过的对象
1> 创建对象时不要直接用类名,一般用self
+ (id)person
{
return [[[self alloc] init] autorelease];
}
<span style="font-size:18px;">/* 1.系统自带的方法里面没有包含alloc、new、copy,说明返回的对象都是autorelease的 2.开发中经常会提供一些类方法,快速创建一个已经autorelease过的对象 1> 创建对象时不要直接用类名,一般用self + (id)person { return [[[self alloc] init] autorelease]; } */int main(){ @autoreleasepool { Person *p = [Person personWithAge:100]; GoodPerson *p2 = [GoodPerson personWithAge:10]; p2.money = 100; } return 0;}</span>
- 黑马程序员-OC笔记(五)内存管理
- 黑马程序员-OC学习笔记-----内存管理
- 黑马程序员----oc加强笔记----内存管理
- 黑马程序员-OC的内存管理笔记
- 黑马程序员-----OC内存管理(一)
- 黑马程序员-----OC内存管理(二)
- 黑马程序员-----OC内存管理(三)
- 黑马程序员(OC内存管理)
- 黑马程序员--OC--内存管理(一)
- 黑马程序员--OC--内存管理(二)
- 黑马程序员 — OC(内存管理)
- 黑马程序员-OC-内存管理
- 黑马程序员--oc:内存管理
- [黑马程序员][OC]内存管理
- 黑马程序员-OC内存管理
- 黑马程序员---OC--内存管理
- 黑马程序员---oc 内存管理
- 黑马程序员-OC-内存管理
- XP系统走了 盖茨来了
- 获取数据库30天内各个指标的TOP语句
- springMVC教程(二)@RequestMapping的基本设置
- Android的5个进程等级
- 工业以太网和CAN现场总线比较
- 黑马程序员-OC笔记(五)内存管理
- 块设备
- js prototype
- hadoop备战:hive命令集
- winform上传文件至服务器
- springMVC教程(三)在controller中获取前台传递的参数
- Android自定义View之--理解视图层
- div添加阴影效果
- shopex如何去掉版权