AutoReleasePool 和 ARC 以及Garbage Collection

AutoReleasePoolhtml

autoreleasepool并非老是被auto 建立,而后自动维护应用建立的对象。app

自动建立的状况以下:ide

 1. 使用NSThread的detachNewThreadSelector:toTarget:withObject:方法建立新线程时,新线程自动带有autoreleasepool。函数

 2. Main thread of Cocoa Applicationoop

 

如下状况须要开发者建立:ui

1. 在使用Dispatch Queue时, 虽然其Pool中每一个thread都会有autoreleasepool,可是若是咱们给的task每一个都建立一些对象,并作autorelease,那若提交的task太多,好比有100000个,那在thread退出前,这些内存都没法释放,等于说有大量内存被占用而释放不了,也相似于leak了,因此这时,最好每一个提交的task都有本身的autoreleasepool,task完成了,对象也释放了,下次再用,再分配,再释放。this

2. 跟1相似的,若是没有函数内部有loop,而且每一个loop都建立不少对象,若是但愿这些对象早点释放,就能够本身建立autoreleasepoolspa

 

 

分析一下现有API的行为。线程

NSString的方法:stringWithCString:encoding:,它建立了一个NSString对象返回了,可是它的方法名中没有Create和Copy,意味着调用者并非这个新建对象的owner。那这个新建对象怎么release呢?autoreleasepool必是其神秘之处,下面一点点说说它。stringWithCString:encoding:这个方法内部没有autoreleasepool,但假设外部的某个方法是在autoreleasepool中的,这个新建对象会在外部的autoreleasepool退出时被释放。而Foundation/Cocoa不少方法都是这样的,就是由于它总体上依赖一个autoreleasepool的嵌套。code

#import <Foundation/Foundation.h>
#include <pthread.h>

void dosth(void *p)
{
    {
        int it = 0;
        while ( it < 10000)
        {
            [NSString stringWithCString:"ajeiauwirejafs" encoding:NSUTF8StringEncoding];
            it++;
        }
    }
}

void * dosth2(void *p)
{
    {
        int it = 0;
        while ( it < 10000)
        {
            [NSString stringWithCString:"ajeiauwirejafs" encoding:NSUTF8StringEncoding];
            it++;
        }
    }
    return NULL;
}
int main(int argc, const char * argv[])
{

    @autoreleasepool {

        for (int i = 0; i<10000; i++) {
            [NSThread detachNewThreadSelector:@selector(dosth) toTarget:NULL withObject:NULL];
            pthread_t pid;
            pthread_create(&pid, NULL, dosth2,NULL);
            sleep(10);
        }
        // insert code here...
        NSLog(@"Hello, World!");
        
    }
    
        return 0;
}

 

ARC(Automatic Reference Counting)

AutoReleasePool确实很好用,不过Apple更推荐ARC(Automatic Reference Counting)。本文的重点是能区分AutoReleasePool和ARC,并不详尽介绍ARC。

Automatic Reference Counting (ARC) is a compiler feature that provides automatic memory management of Objective-C objects. ARC works by adding code at compile time to ensure that objects live as long as necessary, but no longer. Conceptually, it follows the same memory management conventions as manual reference counting by adding the appropriate memory management calls for you.

也就是说ARC是由编译器在编译后的代码中假如retain/release的调用,编译器可让临时对象的生命周期刚恰好,不会过早被release,也不会这个对象再也不须要后好久才释放。概念上说,ARC跟手动管理同样的,可是实际上仍是有不少差异的,好比:既然编译器会插入Release/Retain代码,那程序中就不容许调用retain,release, autorelease等方法了,否则就会形成内存管理的混乱,可是CFRelease,CFRetain仍是能够用的【也就是说,ARC只管ObjectiveC那部分,而管不了C,CoreFoundation那部分】。Wiki上总结了在使用ARC时,有哪些API不能够调用,哪些又必须用。

其中一项是:

“There is no casual casting between id and void *.

You must use special casts that tell the compiler about object lifetime. You need to do this to cast between Objective-C objects and Core Foundation types that you pass as function arguments”

也就是说在将OBJC object和CoreFoundation的对象之间Cast时,必须用特殊的cast操做符进行。

  • __bridge transfers a pointer between Objective-C and Core Foundation with no transfer of ownership.

  • __bridge_retained or CFBridgingRetain casts an Objective-C pointer to a Core Foundation pointer and also transfers ownership to you.

    You are responsible for calling CFRelease or a related function to relinquish ownership of the object.

  • __bridge_transfer or CFBridgingRelease moves a non-Objective-C pointer to Objective-C and also transfers ownership to ARC.

    ARC is responsible for relinquishing ownership of the object.

上面说ARC只管ObjC的对象,无论C/CF的对象,若是一个对象在CF中建立,要拿到ObjC中使用,若是但愿ARC接管这个对象,那就使用__bridge_transfer or CFBridgingRelease,若是不但愿由ARC接管,那就用__bridge。若是一个对象在ObjC中建立,要拿到CF中使用,并由CF/C释放,那就得使用__bridge_retained or CFBridgingRetain,若是还继续由ARC管理,就使用__bridge.

其余的关于ARC的使用限制,就在要使用时一一查看吧,本文对ARC讲到这里,应该已经很清楚ARC跟autoreleasepool的关系了。

 

Garbage Collection

ObjC 2.0 provided an optional conservative, generational garbage collector. 若是enable了garbage collection,那么runtime会将retain/release转成空操做,全部的ObjC对象均可以被回收,而C的对象能够用__strong标记符让GC回收;A zero-ing weak subsystem was also provided such that pointers marked as "__weak" are set to zero when the object (or more simply, GC memory) is collected.可是GC在iOS上performance很差,历来都没有enable过,并且在OS X 10.8上也会设置为deprecated,未来会从OSX中移除。

 

 

Reference:

ARC:https://developer.apple.com/library/mac/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40011226

ARC:http://clang.llvm.org/docs/AutomaticReferenceCounting.html

ARC: http://en.wikipedia.org/wiki/Automatic_Reference_Counting

相关文章
相关标签/搜索