iOS-内存篇 (01~...(05))

01. ARC处理原理

ARC是Objective-C编译器的特性,而不是运行时特性或者是垃圾回收机制,ARC所做的只不过是在代码编译时为你自动在合适的位置插入release或autorelease,只要没有强指针指向对象,对象就会释放。

  • 前端编译器
    前端编译器会为 "拥有的" 每一个对象插入响应的release语句。
    • 如果对象的所有权修饰符是__strong,那么它就是被用有的。
    • 如果在某个方法内创建了一个对象,前端编译器会在方法末尾自动插入release语句以销毁它。而类拥有的对象(实例变量/ 属性),会在dealloc方法内释放。
    • 事实上,你并不需要写dealloc方法或调用父类的dealloc方法,ARC会自动为你完成一切。
    • 此外,由编译器生成的代码甚至会比你自己写的release语句的性能还要好,因为编译器可以做出一些假设。
    • 在ARC中,没有类可以覆盖release方法,也没有调用它的必要。
    • ARC会通过直接使用objc_release来优化调用过程,而相对于retain也是同样的方法。
    • ARC会调用objc-retain来取代保留信息。
  • ARC 优化器
    • 虽然前端编译器听起来是很厉害的样子,但代码中有时仍会出现几个对retain和release的重复调用。
    • ARC优化器负责移除多余的retain和release语句,确保生成的代码运行的速度高于手动引用计数器的代码。

02. 下面关于Objective-C内存管理描述错误的是
A - 当使用ARC来管理内存时,代码中不可以出现autorelease
B - autoreleasepool 在drain 的时候会释放在其中分配的对象
C - 当使用ARC来管理内存时,在线程中大量分配对象而不用 autoreleasepool则可能会造成内存泄露
D - 在使用ARC的项目中不能使用NSZone
参考答案: A

  • 理由:
    • ARC只是在大多时候编译自动为我们添加上内存管理的代码,只是我们的源代码,看不到而已,但是在编译时,编译器会添加上相关的内存管理代码。
    • 对与自动释放池,在drain时会将自动释放池,中的所有对象的引用计数器减一,若引用计数器为0,则会自动释放掉其内存。
    • 如果在线程中需要大量分配内存,我们理应添加上自动释放池,以放内存泄露。
    • 比如在for循环中要分配大量的内存处理数据,那么我们应该在for循环内添加自动释放池,在每个循环就将内存释放掉,防止内存泄露。
    • 在ARC工程中,自然不能手动使用NSZone,也不能调用父类的dealloc.

03.MRC文件在ARC工程混合编译时,需要在文件的Compiler Flags上添加什莫参数?
答: -fno-objc-arc

04. 什莫情况下使用weak关键字,相比assign有什莫不同?

  • 什么情况下使用weak关键字?
    • 在ARC中,在有可能出现循环引用的时候,往往要通过让其中一端使用weak来解决。
    • 比如delegate代理属性。自身已经对它进行一次强引用,没有必要在强引用一次,此时也会使用weak,自定义IBOutlet控件属性一般也使用weak;当然,也可以使用strong.
  • weak和assign的不同?
    • weak此特质表明该属性定义了一种『非拥有关系(nonowning relationship)』。为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。
    • 此特质同assign类似,然而在属性所知的对象遭到摧毁时,属性值也会请空(nil out)。而assign的设置方法只会执行针对『纯量类型(scalar type),例如CGFloat或NSInteger等』简单赋值操作。
    • assign可以用非OC对象,而weak必须用于OC对象。

05. 调用对象的release方法会销毁对象吗?
不会,调用对象的release方法只是将对象的引用计数器-1,而当引用计数器为0时,会调用对象的dealloc方法才能进行释放对象的内存。

你可能感兴趣的:(iOS-内存篇 (01~...(05)))