🚩 | 问题

iphone os有没有垃圾回收机制?简单阐述一下OC内存管理。

📌 | 解答

  • oc中没有垃圾回收机制,只有在Mac上才有,因为手机内存有限,在分配空间给垃圾回收很明显不合适。
  • oc中的内存管理:

    在oc中主要是存在两种类型,一种是值类型(比如:int float 等);一种是父类为NSObject的引用类型。两种类型的内存管理方式不一样,主要是因为他们存放的位置不一样。

    • 值类型:这类主要是存放在栈中。栈是一块连续的内存地址,从高位往下排,但是内存很有限很小;所以栈中的最高位就决定了栈的大小。因为栈在内存中的表现是一块连续的内存,遵循先进先出的原则,所以决定了栈的效率比堆高,而且高的不是一点。同样的,存放在栈中的元素也都是依次排列的。所以不需要我们手动管理。

      虽然栈的效率很高,但是当数据量过高的时候性能明显下降,所以不能将所有的数据都放到栈中;这个时候就要引入另外一个内存概念叫堆了。引用类型的数据就会放入到堆中,栈保存的是这些引入类型在堆中的内存地址;当需要调用时,通过栈中的地址,同样能够很快速的定位到这些数据。

    • 引入类型:引入类型会放入堆中。堆是一块不连续的内存地址。当引入类型放入堆中,给引入类型分配空间时,会随机的从堆中开辟一块内存地址来存放(对,没错,就是这么任性);对象与对象之间的存放也可能会有很多留白,所以就产生了很多的内存碎片,所以就需要我们手动管理。

      在每个对象内存中都有四个字节来存储引用计数,他是一个整数,表示对象的引用次数,系统通过判断这个东西来决定是否收回对象。如果引用计数是0那么就回收对象,如果是不为0,那么就继续保持对象。当对象new alloc retain 的时候引用计数+1,当release的时候引用计数-1

    • 值类型和引入类型之间还是可以相互转换的。把值得类型转换成引入类型叫装箱(例如将int 转换成NSNumber),但是这个过程会增加内存空间,降低性能。将引入类型转换成值类型叫做拆箱(例如把NSNumber 转换成 double)但是注意转换的时候一定要注意数据的原来类型,否则就会失败

  • oc下的内存管理

    • MRC(手动引用计数)iOS5以前的

      这种手动引用计数模式遵循谁创建谁回收的原则,就是谁alloc的就必须由谁release;通过retain assign等缺省关键字来管理内存。

      当引用计数为0的时候就必须要回收对象,如果继续保持对象就会造成内存泄漏。如果引用计数为0之后继续释放就会造成野指针,避免野指针就是在释放之前先将指针置为nil

    • ARC(自动引用计数)

      这货是iOS5以后提出来的,通过strong weak 等缺省关键字来管理内存。只要对象没有强指针引用就会释放。在ARC模式下如果实现dealloc方法,是不允许调用super 方法的。

      ARC模式下的缺省关键字用strong来代替MRC模式下的retain(代表强引用),用weak来代替assgin(代表弱引用),但是weak比之多了一个功能就是如果对象释放了
      指针会自动置为nil。

    • 与内存相关的修饰符

      strong:ARC模式下的跟MRC下的retain一样,强引用;引用计数会+1。

      weak:ARC模式下跟MRC下的assgin一样,弱引用;但是当对象释放之后weak指针会自动置为nil;可以有效避免野指针,他的引用计数为1.

      readonly:只读属性,只会生成getter方法,不会生成setter方法,是不希望属性在外界改变;

      readwrite:读写属性,会生成setter和getter方法。默认的属性

      assgin:赋值属性,不涉及引用计数;setter方法赋值是直接赋值给实例变量

      copy:复制特性;setter方法会将传入的对象先复制一份。

      retain:表示持有特性,引用计数会+1;setter方法会先将参数参数先保留,再赋值。

  • MRC与ARC混编

    理论上不可能混编的,现在大部分都是ARC项目了,所以有时候可能会有一些MRC的三方库导入使用,这时候需要到target中对需要MRC编译的文件添加编译选项-fno-objc-arc

iOS内存管理机制解析:http://www.jianshu.com/p/66b5d43b6ac4

results matching ""

    No results matching ""