iphone 自动引用计数(ARC)











Transitioning to ARC Release Notes









自动引用计数(ARC),是一项为Objective - C程序在编译时提供自动内存管理的功能。ARC可以让你把注意力集中在你感兴趣的代码,对象图,和你的应用程序中的对象之间的关系,让你不必再花费精力在retain和release操作上。正如下图所示,ARC可以减少开发中的内存管理步骤,简化开发。



iphone 自动引用计数(ARC)Contents:

Summary

ARC
Overview


Managing
Toll-Free Bridging


Common
Issues While Converting a Project


Frequently
Asked Questions






概要

ARC工作方式是在代码编译的时候,自动加入内存控制代码,来控制对象的生命周期,确保对象使用的内存空间正确的分配和释放。从概念上来说,ARC遵循Advanced
Memory Management Programming Guide
的手动内存使用守则,通过加入retain,release,autorelease 方法,确保实现与你手动管理内存一样的效果。

为了代码能正常编译,ARC对toll-free bridging(详见“Toll-Free
Bridged Types”
)使用的方式、方法进行了限制,同时ARC还为对象和声明的属性引入了新的生命周期。

ARC支持Mac OS X v10.6/10.7 (64-bit applications) 上的Xcode 4.2,支持iOS4、iOS5。但是ARC在Mac OS X v10.6和iOS4上,不支持Weak references。

Xcode中加入了一个新的工具,用于自动处理ARC里机械式的操作,如移出项目代码中的retain和release方法 调用),而且它还可以帮你修订那些不能自动移植的代码。这个代码移植工具,支持转化项目中的所有代码为ARC模式,如果觉得不方便,你也可以选择手动方式来处理这些文件。







参考资料:





ARC概述

ARC可以代替你去记住何时应该retain,何时应该release,何时要autorelease;ARC回为你评估你的项目所需的生命周期,并且自动地在编译时为你调用适当的方法。编译器还可以帮你生成dealloc方法。一般来说,如果你只使用ARC,当你需要使用手动引用计数的代码互操作的时候,常规Cocoa命名规约是重要的。



一个完整、正确的,用来描述“Person”特性的类的实现(implementation),是这样的:

  1. @interface Person : NSObject@property (nonatomic, strong) NSString *firstName;@property (nonatomic, strong) NSString *lastName;@property (nonatomic, strong) NSNumber *yearOfBirth;@property (nonatomic, strong) Person *spouse;@end @implementation Person@synthesize
    firstName, lastName, yearOfBirth, spouse;@end





( strong 属性的描述参见 “ARC
Introduces New Lifetime Qualifiers”
.)

使用ARC的话,你可以实现一个人为的方法,如下:


  1. - (void)contrived {    Person *aPerson = [[Person alloc] init];    [aPerson setFirstName:@"William"];    [aPerson setLastName:@"Dudney"];    [aPerson:setYearOfBirth:[[NSNumber alloc] initWithInteger:2011]];    NSLog(@"aPerson: %@", aPerson);}



因为使用ARC来管理内存,所以无论是“Person”或者“NSNumber”都不会发生内存泄漏。

你也可以像这样更安全的执行“Person”的“takeLastNameFrom: ”方法:


  1. - (void)takeLastNameFrom:(Person *)person {    NSString *oldLastname = [self lastName];    [self setLastName:[person lastName]];    NSLog(@"Lastname changed from %@ to %@", oldLastname, [self lastName]);}



ARC在NSLog方法调用之前是不会释放oldLastName的。







使用ARC必须遵守的新规则

为了正常运行,ARC引入了一些特有的新规则。新规则的用于提供一个完整可靠的内存管理模式;这些规则有些是用于更好的用户体验,另外一些则是用于简化你的编码,或让你不必再为内存管理操心。如果你违反了这些规则,在你编译的时候就会报错了,而不是当你编译成功,开始运行时出现一些bug。




    不可以再显示调用dealloc、或实现调用retain、release、retainCount、autorelease这些方法。

很明显也不能使用@selector(retain), @selector(release),等等。

当你需要管理一些非实例变量的资源时,你可以实现一个dealloc方法。你不需要也不能去释放实例变量,但您可以调用[systemClassInstance setDelegate:nil]或不使用ARC编译的内存管理代码。

在ARC下去自定义dealloc方法不需要调用 [super dealloc],(实际上如果你调用了 [super dealloc],编译器会报错)。super的调用是由编译器自动强制执行的。

CFRetain, CFRelease, 还有其他Core Foundation-style objects函数 (详见“Managing Toll-Free Bridging”)还是可以执行的。




    不能使用NSAllocateObject或NSDeallocateObject。

    使用alloc来创建对象,由ARC来管理对象运行时的释放。

    不能在C语言的结构体中使用对象指针。

    建议使用Objective-C的class来管理数据格式,来代替C语言的struct。

    不能隐式转换 id和void *。

    你必须告诉编译器转换的类型。当你需要在obj-C的对象和Core Foundation 类型之间转换时,你可以通过函数的参数来做。详见“Managing Toll-Free Bridging”。

    不能使用NSAutoreleasePool对象。

    ARC提供了一个@autoreleasepool块来代替,这个块相比NSAutoreleasePool来说,具有更高的有效性。

    不能使用memory Zone。



    因为现在Objective-C运行时已经忽略NSZone了,所以没必要再使用NSZone了。

为了可以和手动内存管理(manual retain-release)的代码兼容,ARC提出了一些变量方法的命名规约。


    你不能用“new”来做property的名字开头。





ARC引入的新的生命周期修饰符

ARC引入了一些新的生命周期修饰符和zeroing weak引用.。一个weak引用不会改变它所指向对象的生命周期。 一个zeroing weak引用会在它指向的对象被释放以后,自动赋为nil。





在你的程序中,你应该灵活运用修饰符来管理你的对象图。特别是,ARC不会去保护strong引用的retain周期(详见“Practical
Memory Management”
),所以谨慎使用weak可以确保你不会创建循环引用。



Property 属性

在下面的几个例子中,我们介绍一下新的property属性关键词weak、strong。


  1. // 下面的声明和: @property(retain) MyClass *myObject;是一样的@property(strong) MyClass *myObject; // 下面的声明和 "@property(assign) MyClass *myObject;"是相似的,// 但是,当 MyClass 被释放的时候,值被设为nil,而不是一个野指针 @property(weak) MyClass *myObject;



变量修饰符



你可以用下面的生命周期修饰符来声明变量,就像你使用const一样

__strong
__weak
__unsafe_unretained
__autoreleasing



__strong是默认的修饰符。 __weak修饰了一个自动nil的weak引用。__unsafe_unretained声明了一个不会自动nil的weak引用。当变量被释放,那么它就变成了一个野指针了。__autoreleasing 用来修饰一个声明为 (id *)的函数的参数,当函数返回值时被释放。

当你用__weak来修饰栈上的变量时,你必须格外小心。参考下面的例子:

  1. NSString __weak *string = [[NSString alloc] initWithFormat:@"First Name: %@", [self firstName]];NSLog(@"string: %@", string);



虽然string在分配空间并初始化后就被赋值,但是没有别的strong引用对象指向string,所以string被立刻释放了。很明显,NSLog显示出的string值是nil、

同样,你需要在对象值传递时格外注意。下面的代码是可以执行的:

  1. NSError *error = nil;BOOL OK = [myObject performOperationWithError:&error];if (!OK) {    // Report the error.    // ...



However, the error declaration is implicitly:但是,error的声明是隐式的:

NSError * __strong e = nil;



而函数声明是这样的:

-(BOOL)performOperationWithError:(NSError * __autoreleasing *)error;



那么,编译器会重写代码,变成:

  1. NSError __strong *error = nil;NSError __autoreleasing *tmp = error;BOOL OK = [myObject performOperationWithError:&tmp];error = tmp;if (!OK) {    // Report the error.    // ...



当本地变量声明(__strong *error)和函数的参数((NSError * __autoreleasing *)error)不匹配的时候,编译器会创建一个临时变量。当你获得一个__strong变量的地址时,你可以初始化一个id __strong *的指针来声明 ,这样你就可以获得指针的原型,或者你可以声明一个变量为__autoreleasing。





使用生命周期修饰符来避免Strong引用周期

你可以使用生命周期修饰符来避免Strong引用周期。例如,当你制作了一组父子结构的对象,而且父类要引用子类,则会出现Strong引用周期;反之,当你将一个父类指向子类为strong引用,子类指向父类为weak引用,就可以避免出现Strong引用周期。当对象包含block objects时,这样的情况会变的更加隐性。

在手动内存管理模式下, __block id x; 控制x内存计数增加。 在ARC模式下,__block id x默认对x内存技术增加。为了使手动内存管理模式代码可以在ARC模式下正常工作, 你可以用__unsafe_unretained来修饰__block id x;。就和“__unsafe_unretained”字面上的意思一样,;然而,这样一个non-retained变量是危险的(因为它会变成一个野指针) 会带来不良后果。有两种更好一点的方法来处理,一是使用__weak (当你不需要支持iOS 4或OS
X v10.6), 二是设__block值为nil,结束他的生命周期。

下面是手动内存管理的代码,说明了这个问题,

  1. MyViewController *myController = [[MyViewController alloc] init…];// ...myController.completionHandler =  ^(NSInteger result) {   [myController dismissViewControllerAnimated:YES completion:nil];};[self presentViewController:myController animated:YES completion:^{  
    [myController release];}];



如上所述,相反,你可以使用 __block修饰符然后设置myController的值为nil:

  1. __block MyViewController *myController = [[MyViewController alloc] init…];// ...myController.completionHandler =  ^(NSInteger result) {    [myController dismissViewControllerAnimated:YES completion:nil];    myController = nil;};



另外,你还可以使用一个临时__weak变量。下面的例子下面的例子说明了一个简单的实现:

  1. MyViewController *myController = [[MyViewController alloc] init…];// ...__weak MyViewController *weakMyViewController = myController;myController.completionHandler =  ^(NSInteger result) {    [weakMyViewController dismissViewControllerAnimated:YES completion:nil];};



对于一般情况,你可以这样来做:

  1. MyViewController *myController = [[MyViewController alloc] init…];// ...__weak MyViewController *weakMyController = myController;myController.completionHandler =  ^(NSInteger result) {    MyViewController *strongMyController = weakMyController;    if (strongMyController)
    {        // ...        [strongMyController dismissViewControllerAnimated:YES completion:nil];        // ...    }    else {        // Probably nothing...    }};



在某些情况下,比如类不支持__weak模式时,你可以使用__unsafe_unretained。但是,很难保证正确的生命周期,能难或者说不可能去验证一个__unsafe_unretained指针是否有效。





ARC提供一个新的声明来管理Autorelease Pools

使用ARC,你不能再使用NSAutoReleasePool类来直接管理autorelease pools。取而代之,ARC提供了一个新的Objective-C语法来代替。

  1. @autoreleasepool {     // Code, such as a loop that creates a large number of temporary objects.}



通过上面的新语法,可以编译器管理autorelease pools的状态。

在这个@autoreleasepool入口,autorelease pool会压入栈中,当正常退出的时候(break, return, goto, fall-through等),autorelease pool 会出栈,但是当出口代码不兼容,异常退出autorelease pool,则autorelease pool 就不会出栈。

这个语法在所有的Objective-C模式下都能工作。它比NSAutoReleasePool更有效率。建议你把原先的所有NSAutoReleasePool代码都改成新的模式。





Patterns for Managing Outlets Become Consistent
Across Platforms


在被ARC处理过的iOS和OS X中,声明的outlets将会趋于统一。



一般来说outlets变量被修饰为weak,但是如果outlets变量的所有者是nib文件中的top-level对象(或者是storyboard scene)时,应被修饰为strong。



详细参考Resource
Programming Guide
中的“Nib
Files”






栈变量必须初始化为nil

使用ARC模式,strong,weak,autoreleasing栈变量都被隐式的初始化为nil,例如:

  1. - (void)myMethod {    NSString *name;    NSLog(@"name: %@", name);}



运行是程序不会崩溃,NSLog会打印出“null”。





使用编译标识来开关ARC模式

你可以使用 -fobjc-arc来启用ARC。你也可以使用-fno-objc-arc来为某个你希望使用手动管理内存的文件来禁用ARC。

Xcode4.2再MAC OS X10.6和10.7(64位应用)和iOS 4,iOS5支持ARC,Mac OS X 10.6和iOS4不支持weak引用,Xcode4.1以及以前的版本不支持ARC。

你也可以用在一个逐文件处理的方法中使用ARC来手动处理某些文件。For projects that employ ARC as the default approach, you can disable ARC for a specific file using a new-fno-objc-arc compiler flag for that file.



管理 Toll-Free Bridging

在许多的cocoa应用中,你需要用到Core Foundation类型,无论是来自Core Foundation framework本身 (例如CFArrayRefCFMutableDictionaryRef)或是由Core
Foundation扩展出的framework,例如Core Graphics (例如CGColorSpaceRefCGGradientRef).

编译器不会自动管理Core Foundation对象的生命周期;你必须使用CFRetainCFRelease (或相应的特殊类型的变量)
来符合Core Foundation内存管理规则 (详见Memory
Management Programming Guide for Core Foundation
).

如果你在Objective-C和Core Foundation-style类型对象之间转换, 你需要用一个转换(定义在inobjc/runtime.h)或一个Core Foundation-style的宏(定义在NSObject.h),来告诉编译器这个对象的所属关系:

    如果你倾向与用函数调用,你可以用宏例如CFBridgingRetain。这个宏使用新的方法将id和void* 之间转换,并告诉编译器关于这个void*的内存计数器的值。

    1. NS_INLINE CFTypeRef CFBridgingRetain(id X) {    return (__bridge_retain CFTypeRef)X;} NS_INLINE id CFBridgingRelease(CFTypeRef X) {    return (__bridge_transfer id)X;}



    需要使用(__bridge)。

    如果你喜欢C语言式样的转换,你可以直接使用转换:

    1. id my_id;CFStringRef my_cfref;...NSString   *a = (__bridge NSString*)my_cfref;     // Noop cast.CFStringRef b = (__bridge CFStringRef)my_id;      // Noop cast....NSString   *c = (__bridge_transfer NSString*)my_cfref; // -1 on the CFRefCFStringRef d = (__bridge_retained
      CFStringRef)my_id;  // returned CFRef is +1







    编译器处理从CF Objects返回的Cocoa方法



    编译器理解遵从Core Foundation返回的Cocoa命名转换Objective-C方法,(详见Advanced
    Memory Management Programming Guide
    )。例如,编译器知道,在iOS里,CGColor返回的CGColor不属于UIColor。下面的方法来说明:

    1. - (id)initWithCoder:(NSCoder *)aDecoder {    self = [super initWithCoder:aDecoder];    if (self) {        CAGradientLayer *gradientLayer = (CAGradientLayer *)[self layer];        gradientLayer.colors = [NSArray arrayWithObjects:[[UIColor darkGrayColor] CGColor],                                                        
      [[UIColor lightGrayColor] CGColor], nil];        gradientLayer.startPoint = CGPointMake(0.0, 0.0);        gradientLayer.endPoint = CGPointMake(1.0, 1.0);    }    return self;}









    转换函数的参数使用所属关系关键字

    当你用转换Objective-C和Core Foundation对象类型的时候, 你需要去告诉编译器这个传入的参数的所属关系。Core Foundation对象的所属关系规则定义在Core Foundation memory management rules中(详见Memory
    Management Programming Guide for Core Foundation
    );Objective-C对象规则定义在Advanced
    Memory Management Programming Guide
    中。

    下面所示代码中,传入CGGradientCreateWithColors函数的数组需要进行转换。所返回的对象从属关系arrayWithObjects: 没有被传入函数中,转换使用了关键字__bridge。

    1. NSArray *colors = [NSArray arrayWithObjects:[[UIColor darkGrayColor] CGColor],                                            [[UIColor lightGrayColor] CGColor], nil];CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);



    下面的代码演示了,注意所有核心内存管理函数都是遵循基础核心内存管理规则的:

    1. - (void)drawRect:(CGRect)rect {    CGContextRef ctx = UIGraphicsGetCurrentContext();    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();    CGFloat locations[2] = {0.0, 1.0};    NSArray *colors = [NSArray arrayWithObjects:[[UIColor darkGrayColor]
      CGColor],                                                [[UIColor lightGrayColor] CGColor], nil];    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);    CGColorSpaceRelease(colorSpace);  // Release owned
      Core Foundation object.    CGPoint startPoint = CGPointMake(0.0, 0.0);    CGPoint endPoint = CGPointMake(CGRectGetMaxX(self.bounds), CGRectGetMaxY(self.bounds));    CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint,                                kCGGradientDrawsBeforeStartLocation
      | kCGGradientDrawsAfterEndLocation);    CGGradientRelease(gradient);  // Release owned Core Foundation object.}







    转换旧Project使用ARC时出现的共同问题

    当你运行一个已有的项目时,你可能会遇到几个结果,这些是可能出现的后果及解决方案:

    不能使用retain, release, 或autorelease。这是一个特征,而且以下代码也是不允许的这样的代码也是不允许的:

    while ([x retainCount]) { [x release]; }



    不能使用dealloc。

    一般情况下,对于单例模式或者需要替换一个对象的时候,你会在init函数里面调用dealloc函数。对于单例模式,你可以使用共享模式来替代。因为后者在init里面不需要调用dealloc,在你从新对self赋值的时候,原内存就被释放,在init方法中,你并不必须调用dealloc,因为你重构self时,这个对象将会被释放。

    不能使用NSAutoreleasePool 对象。使用新的@autoreleasepool{} 来代替。 它会强制使用一个块在你的autorelease pool,它的速度比NSAutoreleasePool快6倍。甚至@autoreleasepool 还可以在手动内存管理模式下工作。所以无脑使用速度更快的@autoreleasepool来替换掉之前的那些“性能杀手”。



              迁移控制可以使用NSAutoreleasePool但它不能处理复杂的需要考虑的转换,或者用于当变量在 @autoreleasepool的body里被定义的转换之后

    ARC要求在init方法中把[super init]赋值给self。下面的例子是错误的init方法

    [super init];



    应该修改成:

    self = [super init];



    修改后应对,self做nil值检查:

    self = [super init];
       if (self) {
       ...



    你不能自定义实现retain或release方法。实现自定义retain或release方法会破坏weak指针。有下面几个常见的原因来说明为什么不要自定义implementations:

      性能。

      请不要再自定实现这些方法;NSObject中实现retain 和 release 要更快。如果你使用有问题,你应该去解决bug。



      实现weak指针系统。

      使用__weak来代替。 



      实现单例class.

      使用共享模式代替。或者使用类来代替实例函数,来避免对所有的对象分配内存。 


如果你觉得你必须实现自定义retain或release 方法,那么你必须在你的class中实现下面这个方法:


-(BOOL)supportsWeakPointers { return NO; }



这个方法阻止为你的类生成weak指针。但是强烈建议你使用其他的方式来避免实现这些函数。

你不能在C语言的结构体中使用strong ids。

举个例子,下面的代码,编译时会报错:

[pre]struct X { id x; float y; };[/pre]



这是因为,x默认是strongly retained的,当你通过一组完成free操作的代码,传递一个指针进这些结构体,每个id都必须在struct被释放前被释放。但是编译器不能可靠的完成这些,所以结构体中的strong ids在ARC模式中被完全禁止了,必须先释放这些x指向的内存,但是由于是ARC模式,编译器不能安全的去做这些事,所以这些内存泄漏了,所以在C语言的结构中,ARC禁止使用强指针,下面是可能的解决方案:

    使用Objective-C的对象来代替。

    这是最最最好的方法。

    如果使用Objective-C对象不是最优化的选择, (比如你想要一个大量数组的结构体) ,这时用void* 代替。

    这需要使用显示的转换,下面会讨论。

    使用对象的引用__unsafe_unretained。

    下面的方法可以用于这种比较常见模式:

    1. struct x { NSString *S;  int X; } StaticArray[] = {  @"foo", 42,  @"bar, 97,...};



    你可以这样定义结构:

    struct x { __unsafe_unretained NSString *S; int X; }







    这样的写法可能会有问题而且不安全,如果在指针里面的实例被释放了。但是这样做和常量字符一样是共识的很有用的东西。你不能直接进行id和void *的转换(包括核心功能中的类型)。这个问题的细节在 “Managing Toll-Free Bridging”里面讨论。

    你不能直接进行id和void *的转换(包括核心功能中的类型)。这个问题的细节在 “Managing Toll-Free Bridging”里面讨论。





    常见Q&A

    我怎么理解ARC? 在哪调用retains/releases?

    你可以不要再去想什么在哪调用retain/release,你可以花更多的精力来思考你的程序逻辑,对象“strong and weak” 引用, 对象的所属关系,循环引用等问题。



    我还需要给对象写dealloc方法吗?

    可能吧。



    因为ARC不会自动malloc/free,不会管理Core Foundation objects的生存周期,文件描述符等等。你还是需要写dealloc方法去释放资源。

    你不需要也不能去release实体变量,但是你需要在系统的类和没有使用ARC的代码中,调用[self setDelegate:nil]。

    在ARC下,dealloc 方法不是必须的,也不能调用[super dealloc];super在运行时执行。

    循环引用在ARC中还有效吗?

    是的。

    ARC自动管理retain/release,,也继承了循环调用。 幸运的是, ARC模式下的代码很少有内存泄漏,因为在声明的时候就已经决定了是否需要retain。



    ARC模式下块如何工作?

    在ARC模式下,你只能再栈上传递块,例如返回语句。你不需要再使用 Block Copy。但你还是必须在为arrayWithObjects: 传入栈的时候使用[^{} copy]和其他的retain功能的函数。

    有一件事情需要提醒,在ARC模式下,__block NSString *S被保留了,它不是一个野指针。使用_block __unsafe_unretained NSString *S 或者 (更好的方式) __block __weak
    NSString *S.







    我能不能在雪豹Xcode上开发ARC模式的Mac OS程序?

    不行。雪豹版本的Xcode 4.2不支持ARC。雪豹版本没有10.7的SDK,所以在为MAC OS X开发应用的时候不能使用ARC,但是这个版本支持为iOS开发的时候使用ARC。狮子(Lion)版本的是可以的,这意味着你需要在Lion系统中为雪豹构造一个ARC应用

    我能在ARC模式的工程中创建C语言的数组么?

    当然可以, 如下例所示:

    1. // Note calloc() to get zero-filled memory.__strong SomeClass **dynamicArray = (__strong SomeClass **)calloc(sizeof(SomeClass *), entries);for (int i = 0; i < entries; i++) {     dynamicArray[i] = [[SomeClass alloc] init];} // 当你完成时,将所有入口赋值为nil使得ARC释放对象for
      (int i = 0; i < entries; i++) {     dynamicArray[i] = nil;}free(dynamicArray);



    有几点需要注意的是:

      你需要写 __strong SomeClass ** 在某些情况下, 因为默认是__autoreleasing SomeClass **。

      申请的内存空间必须用0填满。



      在释放这个数组前,你必须设置每一个元素为nil(调用memset,并传入0是没有用的)。

      你必须避免使用memcpy 和 realloc。

使用ARC不会不很慢?

这要看你怎么去理解快慢了。但是通常来说“no”,不慢! 编译器有效的排除了很多多余的retain/release的调用,并一直在加快在常规Objective - C代码运行投入很大的努力。尤其是比常规的“返回一个etain/autoreleased 对象”的模式要快得多,而且当调用方法是ARC代码,调用的对象实际上并没有投入autorelease池。

要注意的一个问题是,优化器不是工作在常规的debug设置里面,所以使用-O0 比-Os出现更多的retain/release。

ARC可以在ObjC++模式下工作吗?

可以,你甚至可以在类和容器中使用strong/weak id。ARC在编译时,会在复制构造函数和析构函数中加入retain/release方面的逻辑处理,来确保正常工作。有一点需要避免的就是,你不能为某些指针使用__strong,例如:


std::vector<__strong NSString*> V;



那些类不支持zeroing-weak的weak引用?

下面的类的实例不能使用zeroing-weak的weak引用

NSATSTypesetter, NSColorSpace, NSFont, NSFontManager, NSFontPanel, NSImage, NSMenuView,NSParagraphStyle,NSSimpleHorizontalTypesetter,NSTableCellView,NSTextView,NSViewController,NSWindow, andNSWindowController. 还有,OS X上的AV Foundation框架中所有类都不支持zeroing-weak的weak引用

如果属性变量是这些类的实例的时候,使用assign来替代weak;作为变量,使用__unsafe_unretained来替代__weak。

此外,不用对NSHashTable,NSMapTable, 和NSPointerArray的实例做weak应用。

在写类似NSCell这样使用NSCopyOjbect的子类的时候,有什么需要特别关注的地方么?

没什么特殊的。 ARC来关心你以前增加额外的retains。通过ARC,所有复制方法应该只是复制的实例变量。

我可以为单独文件指定是否使用ARC么?

可以.

当你迁移一个久工程到ARC模式下, -fobjc-arc 编译开关被默认的设置在所有的Objective-C 源代码上。 你可以使用-fno-objc-arc 来为特殊的class停用ARC 。在Xcode的 target的“Build Phases”标签, 打开Compile Sources group,展开源代码列表, 双击你想要修改的源代码的名字,再弹出框里输入-fno-objc-arc,然后点Done按钮。

iphone 自动引用计数(ARC)GC
(Garbage Collection)是否被Mac废弃了?


GC 在Mac OS X v10.7依旧可用.。但是强烈建议你在新工程中使用ARC。对旧的工程(使用手动内存管理或GC),建议你试着去改为ARC模式,然而,这是非零量的工作,你应该权衡与其他优先事项比较之后再去做。

原文链接: https://www.cnblogs.com/zsw-1993/archive/2012/10/12/4880809.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    iphone 自动引用计数(ARC)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/65679

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 上午11:57
下一篇 2023年2月9日 上午11:58

相关推荐