不正经IT从业者

iOS内存优化

2020-03-02  本文已影响0人  Mark_大东

无论面试还是工作希望这篇文章可以解决所有关于iOS内存优化的问题。

所有问题的解决方式都是有基本上的三个提问:是什么?为什么?怎么做?因此对于内存优化的点首先可以做出如下提问:为什么需要内存优化?内存消耗在什么地方?系统是否提供内存管理的方法?处理内存管理的最佳实践有哪些?以上问题在下面的文档中都会提现并作出解答。

为什么内存需要优化?

应用的内存使用量超过单个进程的上线,就会被操作系统终止。

内存的消耗体现在什地方?

内存消耗指的是应用消耗的RAM。应用中内存消耗分为两部分:栈大小、堆大小。每个进程的所有线程共享一个堆空间,每个线程都有专用的栈空间。

堆大小

系统分配给应用的堆大小不会超过512M,同时应用不能控制分配给它的堆,只有操作系统可以管理堆。通过类创建的对象相关的所有数据都存放在堆中。

消耗堆内存的操作:使用NSSting、载入图片、创建使用Json/XML数据等。(待补充)

优化点:图片缓存、数据缓存、降低接口数据大批量输出等。(待补充)

栈大小

栈大小跟线程有关,那么创建线程通常是用来做什么呢?

常见的创建线程有:异步请求、本地缓存sql数据等。更具栈大小的优化点可知不能无限先在创建的线程调用方法。

降低栈大小的操作:相爱时可被递归调用的最大方法树、一个方法最多可以使用的变量数、视图层级在可嵌入的最大深度。

内存的管理模型是什么?

或者说iOS是如何管理内存的?

内存管理模型基于持有关系的概念。如果一个对象正处于被持有关系状态,那它占用的内存就不会被回收。这种持有关系技术通常被称为引用计数。MRC:手动引用计数、ARC:自动引用计数。同时因为ARC的带来的新的引用特性:弱引用。

弱引用:不会增加引用计数,因此不会扩展对象的引用声明周期。

强引用:强引用是默认的引用类型,被强引用指向的内存不会释放,强引用会增加引用计数,同时会扩展对象的声明周期。

自动引用计数:

特点:不在使用retain、release和autorelease;ARC是编译器的一种特性,它会评估对象在代码中,并在编译时自动注入适合的内存管理调用。同时系统默认开始ARC。

变量限定符:

__strong、 _weak 、_unsafe_unretained、 _autoreleasing

Person * _strong p1 = [[Person allon]init];
//创建对象后引用计数为1,并且对象在p1引用期间不会被回收
Person * _weak p2= [[Person allon]init];
//创建对象后引用计数为0,对象会被立即释放,且p2将被置为nil
Person * _unsafe_unretained p3 = [[Person allon]init];
//创建对象后引用计数为0,对象会被立即释放,且p3不会被置为nil
Person * _autoreleasing  p4= [[Person allon]init];
//创建对象后引用计数为1,当方法返回时对象会被立即释放
属性限定符:

strong 、weak 、assign 、copy 、retain 、unsafe_unretained

注意点:布尔类型使用assign限定符、retain是MRC时期的产物

循环引用:

当两个不同的对象各有一个强引用指向对方,就会造成循环引用

循环引用的常见场景:

委托、Blocks、线程与计时器、键值对

处理方式如下:

委托
@protocol TestDataDelegate <NSObject>
- (void)onDataModel;
@end

@interface TestClass
@property (nonatomic,weak) id<TestDataDelegate>delegate;
- (void)delegate;
@end

@implementation TestClass
- (void)cancel{
  self.delegate = nil
}
@end
Blocks
SomeViewController  *vc = [[SomeViewController alloc]init];
_weak typeof(weakSelf) = self;
[self presentViewController:vc animated:YES completion:^{
    typeof(self) theSelf = weakSelf;
    if (theSelf !=nil){
        theSelf.data = vc.data;
        [theSelf dismissViewControllerAnimated:YES completion:nil];
    } 
}];
线程与计时器
- (void)close{
    [self.timer invalidate];
    self.timer = nil;
}
观察者:
- (void)dealloc{
    [self removeObserver];
}

内存分析工具:

使用Instruments选择Leaks进行检测。

内存管理的最佳实践?

备注:关于iOS内存优化先关知识的整理,相关内容来时《高性能iOS开发》、网络资源。以上内容如果需要会在后续慢慢补充完善,知道彻底理解内存相关的知识点。

上一篇下一篇

猜你喜欢

热点阅读