Automatic Reference Counting (ARC)is a compiler feature that provides automatic memory management of objective-C obejcts, Rather than having to think about retain and realease operations,ARC allows you to concentrate on the interesting code,the object graphs,and the relationships between objects in your application。
自动引用计数是一个编辑器特性,它提供自动管理内存的objective-C对象,而不是让去思考关于保留与释放的操作,ARC允许你专注于有趣的代码,对象图以及应用程序中对象之间的关系。
Summary(总结 )
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 (described in advanced Memory Management Programming Guide)by adding the appropriate memory management calls for you.
ARC(Automatic reference Counting)通过在编译时添加代码工作,来确保对象在必要的时候能够存活,但是从概念上来讲,它遵循相同的内存管理约定,因为在手动引用计数(描述在高级内存管理指南)通过添加适当的内存管理调用。
in order for the compiler to generate correct code,ARC restricts the methods you can use and how you use toll-free bridging (see Toll-Free Bridged Types). ARC also introduces new lifetime qualifiers for object references and declared properties.
命令编译器产生正确的代码,ARC限制了你能使用的方法和以及如何使用免费的桥接(Toll-Free Bridged Types)。ARC还为对象的引用和声明属性引进了新的生命限定符。
ARC is supported in Xcode 4.2 for OS X v10.6 and v10.7(64-bit application) and for iOS 4 and iOS 5. Weak references are not supported in OS X v10.6 and iOS 4.
ARC 是在Mac系统OS X v10.6和v10.7中的xcode 4.2以及iOS 4 和iOS 5开始支持的(64位的App)。在OS X v10.6和iOS 4 中不支持弱引用。
Xcode provides a tool that automates the mechanical parts of the ARC conversion (such as removing retain and release calls) and helps you to fix issues the migrator can't handle automatically (choose Edit > Refactor Convert to Objective-C ARC). The migration tool converts all files in a project to use ARC. You can also choose to use ARC on a per-file basis if it's more convenient for you to use manual reference counting for some files.
Xcode 提供了一种工具,可以自动的由ARC部分转化为手动模式部分(MRC手动模式)(例如 删除保留和释放调用),和帮助修复迁移者不能自动处理的问题。 迁移工具将项目中所有的文件转换成使用ARC。如果你使用手动引用计数在一些文件上更方便的话,你也能选择在每个文件的基础上使用ARC.
See also:(参见)
Advanced Memory Management Programming Guide(高级内存管理编程指南)
Memory Management Programming Guide for Core Foundation(核心基础的内存管理编程指南)
ARC Overview(概述)
instead of you having to remember when to use retain , release, and autorelease ,ARC evaluates the lifetime requirements of your objects and automatically inserts appropriate memory management calls for you at compile time.The compiler also generates appropriate dealloc methods for you. In general, if you're only using ARC the traditional Cocoa naming conventions are important only if you need to interoperate with code that uses manual reference counting.
相反,你必须记住何时使用retain,release,and autorelease;ARC评估你的对象的生命周期需求,并在编译时自动插入适当的内存管理调用。编译器还为您生成适当的dealloc方法。在一般的情况下,如果您使用ARC,那么传统的cocoa命名的约定只有在需要与手动引用计数的代码进行交互操作的时候才是重要的。
A complete and correct implementation of a Person class might look like this:
一个完整并正确Person类的实现,可能是这个样子的:
@interface Person : NSObject
@property NSString *firstName;
@property NSString *lastName;
@property NSNumber *yearOfBirth;
@property Person *spouse;
@end
@implementation Person
@end
(Object properties are strong by default; the strong attribute is described in ARC introduces New Lifetime Qualifiers.)
默认下对象的属性是strong ,这个strong描述,是在ARC引入的新的生命周期限定符。
Using ARC, you could implement a contrived method like this:
使用ARC,你可以实现这样的设计方法:
- (void)contrived{
Person *aPerson = [[Person alloc]init];
[aPerson setFirstName:@"William"];
[aPerson setLastName:@"Dudney"];
[aPerson setYearOfBirth:[[NSNumber alloc]initWithInteger:2011]];
NSLog(@"aPerson: %@",aPerson);
}
ARC takes care of memory management so that neither the Person nor the Person nor the NSNumber objects are leaked。
ARC负责管理内存管理,因此不论是是Person还是PersonPerson或NSNumber对象都不会泄漏。
You could also safely implement a takeLastNameForm: Method of Person like this:
你也可以在Person类中安全的实现 takeLastNameForm: 方法像这样:
- (void)takeLastNameFrom:(Person*)person{
NSString* oldlastName = [self lastName];
[self setLastName:[Person lastName]];
NSLog(@"LastName changed form %@ to %@",OldLastName,[self lastName]);
}
ARC ensures that OldLastName is not deallocated before the NSLog statement.
ARC保证OldLastName在NSLog打印之前不被释放。
ARC Enforces New Rules ARC 执行新的规则
To work,ARC imposes some new rules that are not present when using other compiler modes. The rules are intended to provide a fully reliable memory managment model. in some cases, they simply enforce best practice, in some others they simplify your code or are obvious corollaries of your not having to deal with memory management. if you violate these rules, you get an immediate compile-time error, not a subtle bug that may become apparent at runtime.
在工作中,ARC在使用其他编译器模式时强加了一些不存在的新规则。 这些规则旨在提供一个完全可靠的内存管理模型。在某些情况下,它们仅仅执行了最好的实践,在其他一些方面,它们简化了您的代码,或者是您不必处理内存管理的明显结果。如果您违反了这些规则,您会立即得到一个编译错误,而不是一个在运行时可能会变得明显的小错误。
You cannot explicitly invoke dealloc, or implement or invoke retain, release, retainCount, or autorelease.
你不能显式的调用dealloc,或实现或调用retain、release,retainCount,autorelease.
The prohibition extends to using @selector(retain),@selector(release),and so on.
禁止扩展到使用@selector(retain),@selector(release)等。
You may implement a dealloc method if you need to manage resources other than releasing instance variables. You do not have to (indeed you cannot) release instance variables, but you may need to invoke [systemClassInstance setDelegate:nil] on system classes and other code that isn't compiled using ARC.
如果你需要管理其他资源,而不是释放实例变量,那么你可以实现dealloc方法。你不必(事实上你不能)释放实例变量。 但是你可能需要在系统类和不使用ARC编译的其他代码上调用[systemClassInstance setDelegate:nil]。
Custom dealloc methods in ARC do not require a call to [super dealloc](it actually results in a compiler error). The chaining to super is automated and enforced by the compiler.
在ARC中自定义dealloc方法不需要去访问[super dealloc](事实上它导致一个编辑器错误)。这个super链通过编辑器自动化执行。
you can still use CFRetain, CFRelease, and other related functions with Core Foundation-style objects (see Managing Toll-Free Bridging).
在Core Foundation 框架设计对象你仍然能使用CFRetain,CFRelease,和其他关联的功能。(见管理的Toll-Free Bridging)
You cannot use NSAllocateobject or NSDeallocateobject.
You create objects using alloc; the runtime takes care of deallocating objects.
你不能使用NSAllocateobject 和 NSDeallocateobject.
你使用alloc创建对象,运行时负责释放掉对象.
You cannot use object pointers in C structures.
Rather than using a struct, you can create an Objective-C class to manage the data instead.
你在C结构中不能使用对象指针。
你可以创建一个Objective-C的类来管理数据,而不是使用结构体。
there is no casual casting between id and void *.
在id和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. For more details, see Managing Toll-Free Bridging.
你必须使用特殊的计算来告诉编译器的生命周期。你需要在Objective-C对象和作为函数参数传递的核心基础类型之间进行转换。更多的详细细节,见管理对象桥接。
You cannot use NSAutoreleasePool Objects.
你不能使用NSAutoreleasePool对象.
ARC provides @autoreleasePool blocks instead. These have an advantage of being more efficient than NSAutoreleasePool.
ARC 提供了@autoreleasePool 代码块代替。 它们的优势是比NSAotureleasePool更高效。
You cannot use memory zones.
不能使用内存区域.
There is no need to use NSZone any more-they are ignored by the modern Objective-C runtime anyway.
没有必要在使用NSZone——不管怎样,现代Objective-C运行时都忽略它们.
to allow interoperation with manual retain-release code,ARC imposes a constraint on method naming:
允许互操作与手动retain-release代码,ARC强加于一个约束方法命名:
You cannot give an accessor a name that begins with new. this in turn means that you can't,for example, declare a property whose name begins with new unless you specify a different getter:
你不能提供以new开头的访问器名称。例如,这意味着你不能声明一个属性,它的名称不能以new开头,除非你指定了不同的Getter方法:
// Won't work:
@property NSString *newTitle;
// Works:
@property (getter=theNewTitle) NSString *newTitle;
ARC Introduces New Lifetime Qualifiers .
ARC引用新的生命周期限定符.
ARC introduces several new lifetime qualifiers for objects, and weak references. A weak reference does not extend the lifetime of the object it points to, and automatically becomes nil when there are no strong references to the object.
ARC为对象引入了几个新的生命周期限定符,和弱引用,弱引用不会扩展它指向的对象的生命周期。当没有对对象强引用时会自动成为nil。
You should take advantage of these qualifiers to manage the object graphs in your program. In particular, ARC does not guard against strong reference cycles (previously known as retain cycles--see Practical Memory Management). Judicious use of weak relationships will help to ensure you don't create cycles.
你应该利用这些限定符来管理你的程序的对象图。ARC中强引用避免不了的循环调用。(以前称为是retain循环,见实际的内存管理). 明确的使用弱关系有助于确保你不创建循环。
Property attributes 属性财产
The keywords weak and strong are introduced as new declared property attributes, as shown in the following examples.
关键字weak和strong是引用新的公开的属性特性,如下面的例子所示:
// The following declaration is a synonym for:
@property(retain) MyClass *myObject;
@property(strong) MyClass *myObject;
// The following declaration is similar to "
@property(assign) MyClass *myObject;"
// except that if the MyClass instance is deallocated,
// the property value is set to nil instead of remaining as a dangling pointer.
@property(weak) MyClass *myObject;
under ARC,strong is the default for object types.
在ARC下,strong 是对象类型的默认值。
Variable Qualifiers 变量限定符
You use the following lifetime qualifiers for variables just like you would, say, const
对于变量,你使用一下的生命周期限定符,就像你会说 const
__strong
__weak
__unsafe_unretained
__autoreleasing
__Strong is the default. An object remains "alive" as long as there is a strong pointer to it.
__Strong是默认的,只要有一个指向它的强指针,对象就会一直"活动"不释放
__weak specifies a reference that does not keep the referenced object alive. A weak reference is set to nil when there are no strong references to the object.
__weak 指定一个引用,该引用不能保持该引用对象的存活,当对象没有强引用时,weak引用会置nil。
__unsafe_unretained specifies a reference that does not keep the referenced object alive and is not set to nil when there are no strong references to the object. if the object it references is deallocated.the pointer is left dangling.
_unsafe_unretained 指定一个引用,该引用不回保持引用的对象存活,并且在没有对该对象强引用时,也不会置nil,如果该对象的引用释放掉了,那么指针就是野指针。
__autoreleasing is used to denote arguments that are passed by reference variable declaration, the correct format is :
__autoreleasing用来便是引用变量声明传递的参数,正确的格式:
ClassName * qualifier variableName;
for example
MyClass * __weak myWeakReference;
MyClass * __unsafe_unretained myUnsafeReference;
Other variants are technically incorrect but are "forgiven" by the compiler. To understand the issue, see http://cdecl.org/.
其他的变体在技术上是错误的,但是在编译器是可以“原谅”。 要理解这个问题,详见 http://cdecl.org/
Take care when using __weak variables on the stack. Consider the following example:
在堆栈上使用__weak变量时要注意。考虑下面的例子。
NSString * __weak string = [[NSString aloc]initWithFormat:"First Name:%@",[self firstName]];
NSLog(@"string: %@",string);
Although string is used after the initial assignment, there is no other strong reference to the string object at the time of assignment; it is therefore immediately deallocated. The log statement shows that string has a null value.(The compiler provides a warning in this situation.)
尽管字符串在初始化分配之后使用,在作业期间,字符串对象没有其他的强引用,因此立即被释放。日志语句显示该字符串有一个空值。(编译器在这种情况下提供警告)
You also need to take care with objects passed by reference,
你还需要注意引用传递的对象,以下代码将要运用。
NSError *error;
BOOL OK = [myObject performOperationWithError:&error ];
if(!OK){
//Report the error
}
however, the error declaration is implicitly:
然而,这个错误声明是隐式的。
NSError * __strong e;
and the method declaration would typically be:
方法声明通常是:
-(BOOL)performOperationWithError:(NSError * __autoreleasing *)error;
The compiler therefore rewrites the code:
编译器因此改写代码:
NSError * __strong error;
NSError * __autoreleasing tmp = error;
BOOL OK = [myObject performOperationWithError:&tmp];
error = tmp;
if (!OK) {
// Report the error.
// ...
The mismatch between the local variable declaration(__strong)and the parameter(__autoreleasing) cause the compiler to create the temporary variable. You can get the original pointer by declaring the parameter id __strong *when you take the address of a __strong variable. Alternatively you can declare the variable as __autoreleasing .
局部变量声明和参数之间的不匹配,导致编译器创建临时变量。当你使用强壮变量地址时,你能通过声明参数:id _strong,来获取原始指针。或者你可以声明这个变量为 __Autoreleasing.
Use lifetime Qualifiers to Avoid Strong Reference Cycles
使用声明周期限定符避免Strong引用的循环。
You can use lifetime qualifiers to avoid strong reference cycles.for example,typically if you have a graph of objects arranged in a parent-child hierarchy and parents need to refer to their children and vice versa, then you make the parent-to-child relationship strong and the child-to-parent relationship weak. Other situations may be more subtle ,particularly when they involve block objects.
你使用生命周期限定符可以避免强引用循环,举个例子,通常情况下,如果你有一个对象图,在父子层次结构中,父类需要引用他们的子类,反之亦然。然后你使父到子类关系强,子到父类关系弱。其他情况也许更加微妙,尤其当他们包含block对象时。
in manual reference counting mode, __block id x; has the effect of not retaining x. In ARC mode,__block id x; defaults to retaining x(just like all other values). To get the manual reference counting mode behavior under ARC, you could use __unsafe_unretained __block id x;. As the name __unsafe_unretained implies, however, having a non-retained variable is dangerous (because it can dangle)and is therefore discouraged. Two better options are to either use __weak (if you don't need to support iOS 4 or OS X v10.6),or set the __block value to nil to break the retain cycle.
手动应用计数模式(MRC),__block id x; 具有不保留x的效果,在ARC模式下,__block id x; 默认下是保留x的(就像所有其他的值一样)。在ARC模式下拿到手动引用计数模式的这种行为,你可以使用 __unsafe_unretained __block id x . 然而,由于这个名字 __unsafe_unretained 意味着,有一个非保留变量是危险的(因为它可以变化摇摆)因此是一个不鼓励使用的。两个更好的选择是使用__weak(如果你不需要支持iOS4或者OS X v10.6),或者将__block值赋值为nil 来打断retain cycle(循环引用)。
The following code fragment illustrates this issue using a pattern that is sometimes used in manual reference counting.
下面的代码碎片使用了手动引用计数,使用这个手动计数模式来说明上面所提到的retain cycle这个问题。
MyViewController *myController = [[MyViewController alloc] init…];
// ...
myController.completionHandler = ^(NSInteger result) {
[myController dismissViewControllerAnimated:YES completion:nil];
};
[self presentViewController:myController animated:YES completion:^{
[myController release];
}];