OC内存管理

内存管理:

一、范围:
任何继承了NSObject的对象,对基本数据类型无效。
原理:
1.每个对象内部都保存了一个与之相关联的整数,称为引用计数器。
2.当使用alloc、new或者copy创建一个对象时,对象的引用计数器被设置为1。
3.给对象发送一条retain消息,可以使引用计数器值+1。
4.给对象发送一条release消息,可以使引用计数器值-1。
5.当一个对象的引用计数器值为0时,那么它将被销毁,其占用的内存被系统回收,系统也会自动向对象                    发送一条dealloc消息。一般会重写dealloc方法,在这里释放相关资源。一定不要直接调用dealloc方  法。
6.可以给对象发送retainCount消息获得当前的引用计数器值。

二、原则:

1.谁创建,谁释放(“谁污染,谁治理”)。如果你通过alloc、new或(mutable)copy来创建一个对象,那么你必            须调用release或autorelease。换句话说,不是你创建的,就不用你去释放。
2.一般来说,除了alloc、new或copy之外的方法创建的对象都被声明了autorelease。
3.谁retain,谁release。只要你调用了retain,无论这个对象是如何生成的,你都要调用release。

三、@class

通常引用一个类有两种办法:
一种是通过#import方式引入;
一种是通过@class引入;
两种方式的区别:
1、#import方式会包含被引用类的所有信息,包括被引用类的变量和方法;@class方式只是告诉编译器在A.h文件中 B *b 只是类的声明,具体这个类里有什么信息,这里不需要知道,等实现文件中真正要用到时,才会真正去查看B类中信息.
2、使用@class方式由于只需要知道被引用类(B类)的名称就可以了,而在实现类由于要用到被引用类中的实体变量和方法,所以在.m文件中需要使用#import来包含被引用类的头文件.
3、如果有上百个头文件都#import了同一个文件,或者这些文件依次被#improt,那么一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,这样的效率也是可想而知的,而相对来 讲,使用@class方式就不会出现这种问题了.
4、对于循环依赖关系来说,比方A类引用B类,同时B类也引用A类,B类的代码:

#import "B.h"
@interface A : NSObject {

	B *b;
}

#import A.h"
@interface B : NSObject {

	A *a;
}
当程序运行时,编译会报错。当使用@class在两个类相互声明,就不会出现编译报错。
由上可知,@class是放在.h中的,只是在引用一个类,将这个被引用类作为一个类型,在.m实现文件中,如果需要引用到被引用类的实体变量或者方法时,还需要使用#import方式引入被引用类。

四、自动释放池(autorelease pool)

原理:

1.自动释放池是OC里面的一种内存自动回收机制,一般可以将一些临时变量添加到自动释放池中,统一回收释放。
2.当自动释放池销毁时,池里面的所有对象都会调用一次release方法。
3.OC对象只需要发送一条autorelease消息,就会把这个对象添加到最近的自动释放池中(栈顶的释放池)。
4.autorelease实际上只是把对release的调用延迟了,对于每一次autorelease,系统只是把该对象放入了当前的autorelease pool中,当该pool被释放时,该pool中的所有对象会被调用Release。

使用:

一般可以为类添加一个快速创建对象的静态方法

<span style="font-size:18px;">+(id)book {
	return [[[Book alloc] init] autorelease]; 
}</span>
外界调用[Book book]时,根本不用考虑在什么时候释放返回的Book对象

注意:

1.在ARC下,不能使用[[NSAutoreleasePool alloc] init],而应当使用@autoreleasepool。
2.不要把大量循环操作放到同一个NSAutoreleasePool之间,这样会造成内存峰值的上升。
3.尽量避免对大内存使用该方法,对于这种延迟释放机制,还是尽量少用。
4.sdk中一般利用静态方法创建并返回的对象都是已经autorelease的,不需要再进行release操作。
如[NSNumber numberWithInt:10];返回的对象是不需要再release的。
但是通过[[NSNumber alloc] initWithInt:10]创建的对象需要release。

五、property参数:

格式:

@property(参数1,参数2)类型 名字;
参数可有可无, 比如:
@property int age;
@property(nonatomic,retain) UIButton* btn;

参数主要分为3类
读写属性:readwrite/readonly
setter处理:assign/retain/copy
原子性:atomic/nonatomic

atomic:
1.@property属性默认为atomic,提供多线程安全。
2.在多线程环境下,原子操作是必要的,否则有可能引起错误的结果。
3.加了atomic,setter/getter是一个原子操作。如果有多个线程同时调用setter的话,不会出现某一个线程执行setter全部语句之前,另一个线程开始执行setter的情况,相当于函数头尾加了锁一样。

nonatomic:
1.禁止多线程,变量保护,提高性能。
2.atomic是OC使用的一种线程保护技术,防止在写入未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。
3.如果不需要多线程支持的话,用nonatomic就够了,另外由于不涉及锁操作,所以它执行相对快点。

property其他参数:
readwrite: 产生setter\getter
readonly: 只产生简单的getter,没有setter。
assign: 默认类型,setter方法直接赋值,而不进行retain操作
retain: setter方法release旧值,再retain新值
copy: setter方法release旧值,再copy新值


六、ARC(Automatic Reference Counting)

ARC,就是由编译器代码中自动加入了retain/release。要注意的是,ARC并不是GC,它只是一种代码静态分析工具

1.规则
ARC 的规则非常简单:只要还有一个强指针变量指向对象,对象就会保持在内存中。
2.强指针和弱指针
默认所有实例变量和局部变量都是Strong指针。
弱指针指向的对象被回收后,弱指针会自动变为nil指针,不会引发野指针错误。
优点:
1.不需要担心烦人的内存管理和内存泄露。
2.代码的总量变少了。
3.代码效率高,由于使用编译器管理引用计数,减少了低效代码的可能性。
缺点:
1.要记住新的ARC规则、关键字、特性。
2.使用一些旧代码、第三方代码的时候比较麻烦,可能要修改编译开关,XCode4.2中默认ARC是YES的状态。
基本规则:
1.retain, release, autorelease, dealloc由编译器自动插入,不能在代码中调用。
2.dealloc虽然可以被重载,但是不能调用[super dealloc]。
3.不能使用NSAutoreleasePool,应该使用@autoreleasepool块。
4.不能使用”new”开头的属性名称。

ARC关闭方法:

关闭整个项目ARC:

关闭某个.m文件的ARC(如果用-fobjc-arc,代表打开ARC)




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值