性能之内存管理

2017-06-03  本文已影响0人  清水一心

应用中的内存消耗分为:栈大小和堆大小。

栈大小

堆大小

每个进程的所有线程共享一个堆。一个应用可以使用的堆大小通常远远小于设备的RAM值。

自动释放池块(autoreleasepool)

在一些特殊情况下,需要创建自己的autoreleasepool。
* 当你有一个创建了很多临时对象的循环时
* 当你创建一个线程时

ARC的规则

* 不能实现或调用retain、release、autorelease或retainCount方法
  这一规则不仅针对对象,对选择器同样有效
* 可以实现dealloc方法,但不能调用它包括超类
* 不能调用NSAllocateObject和NSDeallocateObject方法
  应该使用alloc方法创建对象,运行时负责回收对象
* 不能在C语言的结构体内使用对象指针
* 不能在 id 类型和void * 类型之间自动转换。如果需要,必须做显示转换。
* 不能使用NSAutoreleasepool,要替换成autoreleasepool
* 不能使用NSZone内寸区域
* 属性的访问器名称不能以new开头,以确保与MRC的互操作性
* Core Foundation类型需要自己手动管理内存

引用类型

变量限定符

属性限定符

这个就不在此做解释了,不懂的,百度上有很多教程

僵尸对象

用来捕捉内存错误的调试功能
通常情况下,当引用计数为0时,对象会立即释放,会使得调试困难。开启僵尸对象,那么对象不会立即释放内存,而是标记为僵尸。
NSZombieEnabled是一个环境变量,可以控制Core Foundation的运行时是否将使用僵尸对象
注意:在发布构建时一定要禁用

内存管理规则

* 你拥有所有自己创建的对象,如new、alloc、copy、mutableCopy
* 你可以用MRC中的retain或ARC中的__strong引用来拥有任何对象的持有关系
* 一定不能抛弃原本并不存在持有关系的对象

循环引用

主要出现的场景委托、块、线程与计时器

观察者

返回错误

当某个方法接收NSError**参数,并在发生错误时填充错误变量,则必须使用__autoreleasing限定符。

弱类型:id

在使用常规命名的方式时,应避免使用id。尽量使用具体的类取而代之。

合理使用全局变量与单例

推荐做法

  避免大量的单例
  对子对象使用__strong
  对父对象使用__weak
  对使引用图闭合的对象(如委托)使用__weak
  对数值属性,使用assign
  对块属性,使用copy限定符
  当声明使用NSError**参数的方法时,需要使用__autoreleasing。并注意用正确的语法: NSError*__autoreleasing *。
  避免在块内直接引用外部的变量。在外用weakify,在内strongify
  销毁计时器、移除观察者、解除回调(例如:委托设置为nil)

扩展

依赖注入(Typhoon和Objection框架)
Instruments进行内存分析

上一篇下一篇

猜你喜欢

热点阅读