现在的位置: 首页 > 综合 > 正文

ARC(Automatic Reference Counting )技术概述

2013年04月18日 ⁄ 综合 ⁄ 共 2456字 ⁄ 字号 评论关闭

此文章由Tom翻译,首发于csdn的blog,任何人都可以转发,但是请保留原始链接和翻译者得名字。多谢!

Automatic Reference Counting (ARC) 是一个编译器的技术,利用此技术可以简化Objective-C编程在内存管理方面的工作量。

这里我把此技术翻译为自动内存计数器管理技术,下图是使用和不使用此技术的Objective-C代码的区别。


ARC技术是随着XCode4.2一起发布的,在缺省工程模板中,你可以指定你的工程是否支持ARC技术,如果你不指定工程支持ARC技术,在代码中你必须使用管理内存的代码来管理内存。

概述

自动计数(ARC)是一个编译期间工作的能够帮你管理内存的技术,通过它,程序人员可以不需要在内存的retain,释放等方面花费精力。

ARC在编译期间为每个Objective-C指针变量添加合适的retain, release, autorelease等函数,保存每个变量的生存周期控制在合理的范围内,以期实现代码上的自动内存管理。

In order for the compiler to generate correct code, ARC imposes some restrictions on the methods you can use, and on how you use toll-free bridging (see “Toll-Free
Bridged Types”
); ARC also introduces new lifetime qualifiers for object references and declared
properties
.

你可以使用编译标记-fobjc-arc来让你的工程支持ARC。ARC在Xcode4.2中引入,在Mac
OS X v10.6,v10.7 (64位应用),iOS 4,iOS 5中支持,Xcode4.1中不支持这个技术.

如果你现在的工程不支持ARC技术,你可以通过一个自动转换工具来转换你的工程(工具在Edit->Convert menu),这个工具会自动所有工程中手动管理内存的点转换成合适自动方式的(比如移除retain, release等)。这个工具会转换工程中所有的文件。当然你可以转换单个文件。

ARC提供自动内存管理的功能

ARC使得你不需要再思考何时使用retain,release,autorelease这样的函数来管理内存,它提供了自动评估内存生存期的功能,并且在编译期间自动加入合适的管理内存的方法。编译器也会自动生成dealloc函数。一般情况下,通过ARC技术,你可以不顾传统方式的内存管理方式,但是深入了解传统的内存管理是十分有必要的。

下面是一个person类的一个声明和实现,它使用了ARC技术。

@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,你可以象下面的方式实现contrived函数:

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

ARC管理内存,所以这里你不用担心aPerson和NSNumber的临时变量会造成内存泄漏。

你还可以象下面的方式来实现Person类中的takeLastNameFrom:方法,

- (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能顺利工作,特增加如下规则,这些规则可能是为了更健壮的内存管理,也有可能为了更好的使用体验,也有可能是简化代码的编写,不论如何,请不要违反下面的规则,如果违反,将会得到一个编译期错误。

  • 下面的这些函数:dealloc,retainreleaseretainCountautorelease。禁止任何形式调用和实现(dealloc可能会被实现),包括使用@selector(retain)@selector(release)等的隐含调用。

    你可能会实现一个和内存管理没有关系的dealloc,譬如只是为了调用[systemClassInstance
    setDelegate:nil]
     ,但是请不要调用[super
    dealloc]
     ,因为编译器会自动处理这些事情。

  • 你不可以使用NSAllocateObject或者NSDeallocateObject.

    使用alloc申请一块内存后,其他的都可以交给运行期的自动管理了。

  • 不能在C语言中的结构中使用Objective-c中的类的指针。

    请使用类类管理数据。

抱歉!评论已关闭.