ARC

article/2025/10/6 9:07:35
自动引用计数(ARC),是一项为Objective - C程序在编译时提供自动内存管理的功能。ARC可以让你把注意力集中在你感兴趣的代码,对象图,和你的应用程序中的对象之间的关系,让你不必再花费精力在retain和release操作上。正如下图所示,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模式,如果觉得不方便,你也可以选择手动方式来处理这些文件。



参考资料:
  • Advanced Memory Management Programming Guide
    Memory Management Programming Guide for Core Foundation


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本身 (例如 CFArrayRef CFMutableDictionaryRef )或是由Core Foundation扩展出的framework,例如Core Graphics (例如 CGColorSpaceRef CGGradientRef ).
编译器不会自动管理Core Foundation对象的生命周期;你必须使用 CFRetain CFRelease  (或相应的特殊类型的变量) 来符合Core Foundation内存管理规则 (详见 Memory Management Programming Guide for Core Foundation ).
如果你在Objective-C和Core Foundation-style类型对象之间转换, 你需要用一个转换(定义在inobjc/runtime.h)或一个Core Foundation-style的宏(定义在NSObject.h),来告诉编译器这个对象的所属关系:
  1. 如果你倾向与用函数调用,你可以用宏例如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禁止使用强指针,下面是可能的解决方案:
  1. 使用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按钮。
GC (Garbage Collection)是否被Mac废弃了?
GC 在Mac OS X v10.7依旧可用.。但是强烈建议你在新工程中使用ARC。对旧的工程(使用手动内存管理或GC),建议你试着去改为ARC模式,然而,这是非零量的工作,你应该权衡与其他优先事项比较之后再去做。

http://chatgpt.dhexx.cn/article/jskQv2Al.shtml

相关文章

ARVR技术 | AR, VR, MR和XR?想搞清楚不?

AR, VR, MR&#xff0c;现在还有XR ?这些缩写是什么?它们代表什么? 让我们快速梳理一下技术术语。 首先&#xff0c;虽然你可能熟悉其中的一些术语&#xff0c;如AR和VR, 但MR和XR对许多人来说仍然是新鲜的术语。 目前的共识是&#xff0c;所有这些互补形式的现实都落在一…

VR与AR简史

点击上方“LiveVideoStack”关注我们 翻译&#xff1a;Alex 技术审校&#xff1a;周昌印 ▲扫描图中二维码或点击阅读原文▲ 了解音视频技术大会更多信息 VR的历史可以追溯到20世纪60年代。早在1961年&#xff0c;Phlico公司的Charles Comeau和James Bryan就开发了一款头显设备…

【iOS】ARC实现

ARC由以下工具来实现&#xff1a; clang&#xff08;LLVM编译器&#xff09;3.0以上objc4 Objective-C运行时库493.9以上 下面我们&#xff0c;我们将围绕clang汇编输出和objc4库的源代码探究ARC实现 1. __strong修饰符 1.1 赋值给附有__strong修饰符的变量 看下面代码 {…

arvix日报0615

百度的阿波罗开源平台架构 Data Driven Prediction Architecture for Autonomous Driving and its Application on Apollo Platform Kecheng Xu, Xiangquan Xiao, Jinghao Miao, Qi Luo Autonomous Driving vehicles (ADV) are on road with large scales. For safe and eff…

【arVix 2021】Masked Autoencoders Are Scalable Vision Learners(MAE)

文章目录 摘要引言方法maskingMAE encoderMAE decoderReconstruction target.Simple implementation. 总结广泛的影响 摘要 本文证明了遮罩自动编码器(MAE)是一种可扩展的计算机视觉自监督学习器。我们的MAE方法很简单:我们掩盖输入图像的随机补丁&#xff0c;并重建缺失的像素…

Corner Cases for Visual Perception in Automated Driving: Some Guidance on Detection ... (arVix 2021)

Corner Cases for Visual Perception in Automated Driving: Some Guidance on Detection Approaches - 自动驾驶中视觉感知的极端案例&#xff1a;检测方法的一些指导&#xff08;arVix 2021&#xff09; 摘要1. 引言2. 极端案例系统化3. 展示极端案例4. 检测方法的概念5. 关联…

大数据可视化技术栈

作者&#xff1a;微澜潮生 链接&#xff1a;https://www.zhihu.com/question/19710815/answer/18592659 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。

大数据可视化期末复习

大数据可视化期末复习 题型考点范围&#xff1a;选择填空判断知识点简述题编程题绘图和例图 题型 选择题&#xff08;30分 /2’&#xff09;判断题&#xff08;10分 /1’&#xff09;填空题&#xff08;20分 /1’&#xff09;简述题&#xff08;24分 /6’&#xff09;编程题&a…

特征可视化技术(CAM)

https://zhuanlan.zhihu.com/p/269702192 CAM技术可以帮助我们理解CNN在图像中寻找目标对象的过程&#xff0c;并且可以用于可视化CNN的中间层特征&#xff0c;以及对图像分类结果的解释和可视化。CAM技术的实现比较简单&#xff0c;可以使用常用的深度学习框架如PyTorch和Te…

大数据可视化学期总结

学期总结 知识点总结个人总结 知识点总结 个人总结 在本学期的开始&#xff0c;我们接触了一门新兴的课程—大数据可视化。数据可视化&#xff0c;是关于数据视觉表现形式的科学技术研究。其中&#xff0c;这种数据的视觉表现形式被定义为&#xff0c;一种以某种概要形式抽提出…

深度神经网络可视化技术

深度神经网络可视化技术 深度学习模型表述的难点与意义深度神经网络的可视化云脑 Deepro 采用的 CNN 可视化独立单元激活的可视化图案和区域生成法云脑 Deepro 采用的 RNN 可视化LSTM 解释元与激活门统计 人工智能模型可视化实例结语 深度学习模型表述的难点与意义 深度神经网…

三维可视化技术的应用现状及发展前景

地质体的三维建模与可视化结合基础的自然地理数据信息、钻孔数据信息、物探解译模型数据信息&#xff0c;运用有关技术搭建三维空间数据场&#xff0c;选用硬件配置技术完成系统化。它应用可视化技术揭示了地下世界&#xff0c;是地质学的前沿课题研究之一。以可视化技术为基础…

大屏可视化关键技术

大屏可视化的技术中涉及的范围会比较广&#xff0c;拆开来说诸如各种LED视频技术、互联网技术、智能技术、视觉设计技术等等这些技术&#xff0c;都是跟大屏可视化有着千丝万缕断不开的关系&#xff0c;但真正影响到大屏可视化关键技术却在于下面的3点上。 大屏可视化关键技术&…

大数据可视化技术与应用作业一的经验总结

大数据可视化技术与应用的作业一总结 可视化课的第一次作业&#xff0c;老师让我们参照课本做出个性化的词云图&#xff0c;以下是此次做作业过程中关于背景色&#xff0c;成品效果不好等等问题的总结。 最终做出的词云图&#xff1a; 这是我参考书本上的例子经修改过后运行…

CNN可视化技术总结(一)--特征图可视化

导言&#xff1a; 在CV很多方向所谓改进模型&#xff0c;改进网络&#xff0c;都是在按照人的主观思想在改进&#xff0c;常常在说CNN的本质是提取特征&#xff0c;但并不知道它提取了什么特征&#xff0c;哪些区域对于识别真正起作用&#xff0c;也不知道网络是根据什么得出了…

机器学习可视化技术(Towards Data Science)

介绍 作为任何数据科学项目的一部分&#xff0c;数据可视化在了解更多可用数据和识别任何主要模式方面发挥着重要作用。 如果能够使分析中的机器学习部分尽可能直观&#xff0c;那不是很好吗&#xff1f; 在本文中&#xff0c;我们将探讨一些可以帮助我们应对这一挑战的技术&am…

大数据可视化技术面临的挑战及应对措施

来源&#xff1a;科技导报 本文约5400字&#xff0c;建议阅读10分钟 本文介绍了适用于大数据的数据可视化技术&#xff0c;讨论了针对大数据可视化应用需求自主研发的交互式可视化设计平台AutoVis及其应用。 [ 导读 ]本文从大数据本身的特点及其应用需求出发&#xff0c;结合数…

大数据可视化技术应用学习目标与复习小结

大数据可视化技术与应用 一、大数据可视化概述学习目标1.1 什么是大数据可视化&#xff1a;1.2 大数据可视化的类型1.3大数据可视化的标准 1.4大数据可视化的作用1.5大数据可视化的特征 二、大数据可视化原理学习目标2.1 光源种类&#xff0c;原色、间色、复色概念&#xff0c;…

三维可视化技术都有哪些运用

伴随着数据在当前互联网技术迅速发展壮大下变的层面更广&#xff0c;总数更大、构造愈来愈繁杂&#xff0c;大家如果想要更加清楚&#xff0c;迅速的认识和了解一份数据&#xff0c;传统化的二维平面图数据图表现已不能够满足需求&#xff0c;三维可视化技术越融合多媒体技术、…

【可视化开发】数据大屏可视化技术汇总

由于工作原因&#xff0c;需要用到一些大屏可视化技术&#xff0c;于是通过网上整理、自我学习等多途径&#xff0c;汇总了一份大屏可视化技术的思维导图&#xff0c;如下&#xff1a; 这里主要汇总的是&#xff1a; 大屏可视化技术&#xff01; 大屏可视化技术&#xff01; …