ARC内存优化

ARC虽然是自动引用计数,但我们在进行ARC开发的时候也需要注意一些问题如一下四点:

一.ARC下需要注意:

1.在ARC下使用音频播放器来播放音乐的时候,要注意要将AVAudioPlayer声明成属性,来提高播放器的声明周期,要不然是不会进行音乐播放的

//  *1.在ARC播放音频文件的时候,记得提高音频播放器的生命周期

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"小苹果" ofType:@"mp3"];

NSURL *fileURL = [NSURL fileURLWithPath:filePath];

self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];

[_audioPlayer play];

2.在使用KVO的时候,我们要把观察者声明成属性,要不然会系统崩溃,访问一块坏的内存,因为观察者要持续观察被观察者属性的变化,而ARC是编译器自己在

适合的地方为我们加上release进行内存管理,观察者对象的释放不由我们控制,我们仍然要把观察者声明成属性,来提高观察者对象的声明周期,让观察者

对象不能提前释放

//  *2.KVO使用的时候

self.secVC = [[SecondViewController alloc] init];

[self addObserver:_secVC forKeyPath:@"lanouNumber" options:NSKeyValueObservingOptionNew context:NULL];

3.ARC下也需要注意内存的循环引用问题,循环引用就是两个对象相互引用,导致两个对象的内存都没有办法释放,从而引起内存泄露

//  3.循环引用现象

//  teacher:1

Teacher *teacher = [[Teacher alloc] init];

//  student:1

Student *student = [[Student alloc] init];

//  student:2

teacher.stu = student;

//  teacher:2

student.tea = teacher;
//  解决arc下循环引用问题:

//  弱化其中任何一个强引用属性,打破强引用链,在当前的例子中就是在Teacher类中将student的属性变化weak
//  weak,也可以使用assign
//  weak修饰对象类型,不能修饰基础类型,assign可以修饰对象类型,也可以修饰基础类型,区别:weak修饰的属性在dealloc之后,会进行安全处理,将该属性自动赋值为nil
4.arc下block的循环引用及解决方案

//  4.arc下block的循环引用
//  arc下出现block的循环引用,解决方案:在block中使用__weak修饰的变量

Teacher *tea = [[Teacher alloc] init];

Teacher *teacher = tea;

//  下面的使用方式,就会出现循环引用现象

[tea setMyBlock:^{

NSLog(@"%@", teacher);

}];
解决方法:

在变量将要被引入到block块中之前,在ARC下添加__weak关键字,MRC下使用__block关键字
__weak Teacher *teacher = tea;
二. 程序受到内存警告之后的处理

- (void)didReceiveMemoryWarning {

[super didReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

//  1.用来判断当前控制器的视图有没有被加载过

//  2.我们可以通过这个属性来判断当前这个view有没有在window上显示

if (self.isViewLoaded && !self.view.window) {

//  1.我们可以把一些强引用属性赋值为nil

//  2.我们可以把当前控制器的view置为nil,用来节省内存,我们再次切换到这个控制器的时候,系统会自动再次触发loadView方法帮助我们创建view

//  释放声明的强引用属性

self.lanouNumber = nil;

self.audioPlayer = nil;

self.secVC = nil;

//  将控制器的view置为nil,因为控制器的view没有在window上显示,节省资源

self.view = nil;

NSLog(@"rootView dead");

}

}
三.ARC下autoreleasepool的使用

ARC下使用NSThread创建的子线程,在子线程中执行的方法中,系统并没有为我们创建自动释放池,所以一些autorelease的属性不能及时释放,当

我们写到了release/retain等方法, ARC 下你不能写这些方法,但ARC

会帮你在合适的地方插入这些方法。这将导致内存的延迟释放。autoreleasepool是为了 autorelease

这个方法,在对象的创建者没法销毁对象的时候,可以使用autorelease让autoreleasepool每隔一段时间检查该对象的引用计数,如果

为0则释放对象。那么多个autoreleasepool的作用就是增加这种间隔,比原本autorelease释放的时间更早释放。

所以无论在ARC还是MRC我们使用NSThread的时候,方法中需要加入自动释放池

//  NSThread

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadAction:) object:nil];

//  手动开启

[thread start];

//  就是在子线程中去执行的方法

- (void)threadAction:(NSThread *)sender

{

//  我们无论在ARC下还是MRC,在NSThread方法中都需要我们把新增的对象类型放到autoreleasepool。

//  *因为NSThread开辟子线程中并没有自动释放池,没有办法对autorelease修饰的类型进行释放

@autoreleasepool {

NSLog(@"-----%d", [NSThread isMainThread]);

Teacher *teacher = [[Teacher alloc] init];

}

}

来自:http://www.jianshu.com/p/4ac5e7d7d672?utm_campaign=maleskine&utm_content=note&utm_medium=reader_share&utm_source=weixin&from=timeline&isappinstalled=0

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值