看啥推荐读物
专栏名称: 尝山爪子茸
目录
相关文章推荐
今天看啥  ›  专栏  ›  尝山爪子茸

OC内存管理

尝山爪子茸  · 掘金  ·  · 2021-02-09 22:42
阅读 28

OC内存管理

1 OC的内存管理

通过引用计数器(returnCount)的机制来决定对象是否需要释放,每次runloop完成一个循环的时候,就会检查对象的retainCount,如果returnCount为0,说明没有对于该对象的引用,该对象可以被释放掉,当引用计数减为零之后,系统会自动调用dealloc方法回收内存。

黄金法则:如果对一个对象使用了alloc,copy,mutablecopy,retain,必须要有与之对应的release,autorealse。

1.1 内存管理的原因

内存有限,一个程序占用的内存也有限,当需要使用的内存超出程序分配到的的内存时,程序就会crash闪退。对于内存进行管理,在合适时间清理掉被占用的内存空间,可以提高内存的利用率,让程序运行更加流畅

1.2 内存管理的范围

内存管理管理的是继承于NSObject的对象和block,其他非对象不需要管理。 OC对象存放在堆内,非OC对象存放在栈内。堆内存是动态分配的,需要手动分配回收;而栈是由系统分配回收。

1.3 内存管理的方式

  • MRC(manual retain-release)/MRR(manual retainCount-release) 手动内存管理
  • ARC(automatic reference counting) 自动引用计数,在iOS5.0版本后推出,只要没有强指针指向对象,对象就会被释放,编译器隐式管理内存,在适当的位置插入retain,release,autorelease
  • Garbage collection(垃圾回收) MacOS开发中支持GC,iOS不支持垃圾回收

2 内存泄漏

对象没有再被使用,但这个对象没有被销毁,空间没有被释放

2.1 内存泄漏的情况

  • 对象间的相互强引用

strong A -> strong B -> strong A,比如对于delegate属性使用weak而不用strong,delegate也可以使用assign,assign进行指针拷贝可以指向对象,对象被销毁的时候指针不会自动置为nil,有可能发生野指针的情况,但对于delegate,delegate指向的对象生存期会覆盖持有delegate的对象的生存期,该隐患就不成立,但使用weak更安全,比如说delegate指向的对象是某个ViewController的属性,该ViewController被销毁了,delegate指向的对象作为其属性也应该被销毁,但是其又被一个其他对象强引用了导致其没有销毁,这时,assign的delegate指向了本该被销毁的对象

  • 在循环内创建的临时变量的对象

由于循环次数过多,在循环中产生了大量的临时变量,每次循环都会有一个NSString* 的对象加入当前runloop的自动释放池当中,只有自动释放池被释放的时候,这些加入的NSString才会被释放,那么如果循环次数特别大,内存被消耗光,出现内存溢出

循环次数比较大时 使用@autoreleasepool{}框住外面

循环次数特别大时,使用@autoreleasepool{}框住里面

在离开autoreleasepool作用范围后会对里面的对象进行一次release,并不保证一定销毁掉对象

for(int i = 0; i < 1000000; i++){
	NSString * s = ...
    //dosomething
}
复制代码
  • 无限循环

比如ViewController内设置了一个循环次数为HUGE_VAL近乎无限循环的动画,ViewController消失的时候不能被释放。 应该在viewWillDisappear当中移除该动画




原文地址:访问原文地址
快照地址: 访问文章快照