12.使用ARC的程序的编译
启用ARC编译代码时,不能使用gcc而要使用clang。
不用在dealloc中释放实例变量(但可以在dealloc中释放资源),也不需要调用[super dealloc]
使用@autoreleasepool、代替NSAutoreleasePool
编译代码时使用编译器clang,并加上编译选项-fobbjc-arc
13.循环引用和弱引用
关于垃圾回收
14.垃圾回收(garbage collection)指的是在程序运行过程中不定时地检查是否有不再使用的对象,如果存在就释放它们占用的内存空间。通常被简称为GC,内存的检查和回收都是由垃圾收集器(garbage collector)完成的。为了更好的利用垃圾回收,需要了解垃圾回收的原理和内部机制。垃圾回收只能用在Mac OS X的软件中,Mac OS X 10.7和iOS 5 以上的系统强烈建议使用ARC来管理内存,垃圾回收仅仅是作为一种备选的方案而存在的。
15.垃圾回收的目标是不再使用的实例对象,C风格的变量,C风格的结构体以及C风格申请的内存都不属于垃圾回收的范围。id类型,以类名作为类型(例如NSobject * 类型)的实例对象是垃圾回收的目标。通过全局变量,静态变量或者栈内变量的引用而查找到的对象都不可以被回收,反之,只要从根集合出发无法到达的对象都属于垃圾回收的目标。
垃圾收集器的运行是自适应的,既不以固定的频率运行。当程序运行过程中分配的内存超过一定量时,垃圾收集器就会被自动出发运行。垃圾收集器通常作为一个单独的线程运行,并对已经不再被使用的对象进行回收,整个回收过程是根据程序韩勇内存的多少自动完成的。
一个程序只有一个垃圾回收期,通常在主线程(mainthread)中运行。每个线程都有自己的栈空间,这些栈控件中的变量不属于垃圾回收的范畴。垃圾收集器运行的时候有可能会暂停其他线程来完成垃圾收集,但不会暂停所有线程的运行。
虽然垃圾收集器会根据内存的情况自动运行,但我们也可以通过给类NSGarbageCollector发送collectIfNeeded消息来启动垃圾收集器。特别是当我们大量使用了临时对象时,可以通过这种方法来释放内存。通过主动启动垃圾回收,不仅可以控制内存的消费,又可以避免垃圾回收突然启动程序反映变慢的问题。
垃圾收集器并不是一找到不再使用的对象就立刻释放它,而是会首先找到所有不再使用的对象,然后再给这些对象发送finalize消息。等所有对象相应了finalize之后,才释放这些对对象。垃圾收集环境下释放对象时,对象的dealloc方法不会被执行。
finalize方法的定义
在对象被回收释放之前,finalize方法会被执行,除了子类中调用父类的finalize之外,程序中不允许直接调用finalize方法。原则上不推荐轻易定义finalize,只有碰到finalize就无法实现的功能时才建议定义finalize。
垃圾回收在一个独立的线程中执行,同软件本身是并行的关系,如果finalize处理过于复杂的话就会影响软件本身的执行速度。
要被释放的对象的finalize方法的执行是没有先后顺序的,不要依赖finalize方法的执行顺序来做任何事情。
实现finalize方法需要注意下面几项:
(1)finalize方法内不用担心其他对象的释放
(2)要注意finalize方法中对象的赋值
(3)finalize的执行顺序和对象的释放顺序都是无法确定的
(4)finalize不是线程安全的,线程安全是指某个函数在多线程环境中被调用时,也能够够正确处理各个线程的局部变量。特别是处理多个实例共有的对象或资源时,特别注意。
启用垃圾回收后,retain,release,autorelease,dealloc,retainCount这些方法都无法使用。
垃圾回收的引入,类NSAutoreleasePool增加了新方法,-(void)drain,在垃圾回收的管理中,drain方法表示申请进行垃圾回收,和后面提到的类NSGarbageCollectr的collectIfNeeded方法具备同样的功能。