illustrate ARC with graphs

by admin on 2020年5月8日

Rust 1. 4 发布,更新内容如下:

Rust 1.3 发布,该版本最显著的变化是 announcement API
zero-filling 方法用于初始化和调整向量,提升了 Read::read_to_end
函数的速度(via  。

澳门新葡亰网址下载 1


澳门新葡亰网址下载 2


  • Windows builds targeting the 64-bit MSVC ABI and linker (instead of
    GNU) are now supported and recommended for use.


  • The new object lifetime
    have been turned on
    after a cycle of warnings about the change. Now types like
    &'a Box<Trait> (or &'a Rc<Trait>, etc) will change from being
    interpreted as &'a Box<Trait+'a> to &'a Box<Trait+'static>.

  • The Rustonomicon is a
    new book in the official documentation that dives into writing
    unsafe Rust.

  • The
    API, has been
    stabilized. This
    basic unit of timekeeping is employed by other std APIs, as well as
    out-of-tree time crates.

澳门新葡亰网址下载 3


  • Several changes have been made to fix type soundness and improve
    the behavior of associated
    types. See RFC
    Although we have mostly introduced these changes as warnings this
    release, to become errors next release, there are still some
    scenarios that will see immediate breakage.

  • The str::lines and BufRead::lines iterators treat rn as
    line breaks in addition to

  • Loans of 'static lifetime extend to the end of a

Breaking Changes

  • The new object lifetime
    have been turned on
    after a cycle of warnings about the change.

  • There is a known
    澳门新葡亰网址下载 ,regression in how
    object lifetime elision is interpreted, the proper solution for
    which is undetermined.

  • The #[prelude_import] attribute, an internal implementation
    detail, was accidentally stabilized previously. It has been put
    behind the prelude_import feature
    gate. This change is
    believed to break no existing code.

  • The behavior of
    ismore sane for dynamically sized
    types. Code that
    relied on the previous behavior is thought to be broken.

  • The dropck rules, which checks that destructors can’t access
    destroyed values, have been
    updated to match
    This fixes some soundness holes, and as such will cause some
    previously-compiling code to no longer build.

澳门新葡亰网址下载 4


  • use statements that import multiple items can now rename
    them, as in
    use foo::{bar as kitten, baz as puppy}.

  • Binops work correctly on fat

  • pub extern crate, which does not behave as expected, issues a
    warning until a
    better solution is found.


  • The new object lifetime
    have been turned on
    after a cycle of warnings about the change.

  • Semicolons may now follow types and paths in

  • The behavior of
    ismore sane for dynamically sized
    types. Code that
    relied on the previous behavior is not known to exist, and suspected
    to be broken.

  • 'static variables may now be

  • ref bindings choose between

  • The dropck rules, which checks that destructors can’t access
    destroyed values, have been
    updated to match

澳门新葡亰网址下载 5


  • Many APIs were
    IntoRawHandle,IntoRawSocket::into_raw_socket, IntoRawSocket,

  • Some APIs were
    BTreeMap::with_b,BTreeSet::with_b, Option::as_mut_slice,
    Option::as_slice,Result::as_mut_slice, Result::as_slice,

  • Reverse-searching strings is faster with the ‘two-way’

  • std::io::copy allows ?Sized

  • The Windows, Chunks, and ChunksMut iterators over slices
    alloverride count, nth and last with an O(1)

  • Default is implemented for arrays up to
    [T; 32].

  • IntoRawFd has been added to the Unix-specific
    prelude,IntoRawSocket and IntoRawHandle to the Windows-specific

  • Extend<String> and FromIterator<String are both implemented

  • IntoIterator is implemented for Option<&T>

  • HashMap and HashSet implement Extend<&T> where
    T: Copy as part of

  • BinaryHeap implements

  • Borrow and BorrowMut are implemented for fixed-size

  • extern fns of with the “Rust” and “C” ABIs implement common
    traits including Eq, Ord, Debug,

  • String comparison is

  • &mut T where T: Write also implements

  • A stable regression in VecDec::push_back that caused panics for
    zero-sized types was

  • Function pointers implement traits for up to 12


  • The
    API, has been
    stabilized, as well
    as thestd::time module, which presently contains only Duration.

  • Box<str> and Box<[T]> both implement Clone.

  • The owned C string,
    and the borrowed C string,
    The two of these allow C strings to be borrowed and cloned in
    generic code.

  • CStr

  • AtomicPtr

  • Error
    trait objects can be downcast to their concrete
    typesin many common
    configurations, using the
    methods, similarly to

  • Searching for substrings now employs the two-way
    algorithminstead of
    doing a naive search. This gives major speedups to a number of
    methods, including
    are also faster.

  • The performance of PartialEq for slices is much

  • The
    trait offers the default method,
    which is overridden and optimized by the implementations for

  • The
    trait now has a number of specialized write_*methods for primitive
    types, for efficiency.

  • The I/O-specific error type,
    gained a set of methods for accessing the ‘inner error’, if any:
    As well, the implementation of
    also delegates to the inner error.

  • process::Child
    gained the
    method, which returns au32 representing the platform-specific
    process identifier.

  • The
    method on slices is deprecated, replaced by the
    method (note that both of these are on the
    trait, but through the magic of the prelude are available to stable
    code anyway).

  • The Div
    operator is implemented for

  • DerefMut is implemented for

  • Performance of SipHash (the default hasher for HashMap) isbetter
    for long data.

  • AtomicPtr

  • The
    implementations for
    now specialized to use uninitalized buffers for increased

  • Lifetime parameters of foreign functions are now resolved

澳门新葡亰网址下载 6


  • The compiler no longer uses the ‘morestack’ feature to prevent
    stack overflow.
    Instead it uses guard pages and stack probes (though stack probes
    are not yet implemented on any platform but Windows).

  • The compiler matches traits faster when projections are

  • The ‘improper_ctypes’ lint no longer warns about use of isize

  • Cargo now displays useful information about what its doing
    duringcargo update.



文章转载自:开源中国社区 []    


  • Rust can now, with some coercion, produce programs that run on
    Windows XP, though XP
    is not considered a supported platform.

  • Porting Rust on Windows from the GNU toolchain to MSVC continues
    4). It is still not
    recommended for use in 1.3, though should be fully-functional in the
    64-bit 1.4

  • On Fedora-based systems installation will properly configure the

  • The compiler gained many new extended error descriptions, which can
    be accessed with the --explain flag.

  • The dropck pass, which checks that destructors can’t access
    destroyed values, has been
    rewritten. This fixes
    some soundness holes, and as such will cause some
    previously-compiling code to no longer build.

  • rustc now uses LLVM to write archive files where
    possible. Eventually
    this will eliminate the compiler’s dependency on the ar utility.

  • Rust has preliminary support for i686
    (it has long supported FreeBSD on x86_64).

  • The unused_mut,
    lints are more strict.

  • If landing pads are disabled (with -Z no-landing-pads),
    panic!will kill the process instead of


Rust 是 Mozilla 的一个新的编程语言,由web语言的领军人物Brendan
Eich(js之父),Dave Herman以及Mozilla公司的Graydon Hoare 合力开发。

文章转载自:开源中国社区 []    

澳门新葡亰网址下载 7

澳门新葡亰网址下载 8


澳门新葡亰网址下载 9
澳门新葡亰网址下载 10


澳门新葡亰网址下载 11

澳门新葡亰网址下载 12

澳门新葡亰网址下载 13

澳门新葡亰网址下载 14



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
by adding the appropriate memory management calls for you.

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
ARC also introduces new lifetime qualifiers for object references
and declared

ARC is supported in Xcode 4.2 for OS X v10.6 and v10.7 (64-bit
applications) and for iOS 4 and iOS 5. Weak references are not supported
in OS X v10.6 and 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.

See also:

  • Advanced Memory Management Programming

  • Memory Management Programming Guide for Core

ARC Overview

Instead of you having to remember when to use retainrelease,
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.

A complete and correct implementation of a Person class might look
like this:

@interface Person : NSObject
@property NSString *firstName;
@property NSString *lastName;
@property NSNumber *yearOfBirth;
@property Person *spouse;
@implementation Person

(Object properties are strong by default; the strong attribute is
described in “ARC Introduces New Lifetime

Using ARC, you could implement a contrived method like this:

- (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 NSNumber objects are leaked.

You could also safely implement a takeLastNameFrom: method
of Person like this:

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

ARC ensures that oldLastName is not deallocated before
the NSLog statement.

ARC Enforces New Rules

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 management 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.

  • You cannot explicitly invoke dealloc, or implement or
    invoke retainreleaseretainCount, or autorelease.

    The prohibition extends to
    using @selector(retain)@selector(release), and so on.

    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.

    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.

    You can still use CFRetainCFRelease, and other related
    functions with Core Foundation-style objects (see “Managing Toll-Free

  • You cannot use NSAllocateObject or NSDeallocateObject.

    You create objects using alloc; the runtime takes care of
    deallocating objects.

  • 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.

  • 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. For
    more details, see “Managing Toll-Free

  • You cannot use NSAutoreleasePool objects.

    ARC provides @autoreleasepool blocks instead. These have an
    advantage of being more efficient than NSAutoreleasePool.

  • You cannot use memory zones.

    There is no need to use NSZone any more—they are ignored by the
    modern Objective-C runtime anyway.

To allow interoperation with manual retain-release code, ARC imposes a
constraint on method naming:

  • 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:

    // Won't work:
    @property NSString *newTitle;
    // Works:
    @property (getter=theNewTitle) NSString *newTitle;

ARC Introduces New Lifetime Qualifiers

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.

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
Judicious use of weak relationships will help to ensure you don’t create

Property Attributes

The keywords weak and strong are introduced as new declared property
attributes, as shown in the following examples.

// 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.

Variable Qualifiers

You use the following lifetime qualifiers for variables just like you
would, say, const.

  • __strong is the default. An object remains “alive” as long as
    there is a strong pointer to it.

  • __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.

  • __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.

  • __autoreleasing is used to denote(指示) arguments that are
    passed by reference (`id
    `) and are autoreleased on return.*

You should decorate variables correctly. When using qualifiers in an
object variable declaration, the correct format is:

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 .

Take care when using __weak variables on the stack. Consider the
following example:

NSString * __weak string = [[NSString alloc] 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 stringhas a null value. (The compiler provides a warning in this

You also need to take care with objects passed by reference. The
following code will work:

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) causes 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
strongvariable. Alternatively you can declare the variable

1 //可以写成这样?挺难看
2 -(BOOL)XXXXX:(NSError __strong *)err
3 {
4     NSError *__autoreleasing temperr = err;
5     [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&temperr];
6 }


Use Lifetime Qualifiers to Avoid Strong Reference Cycles

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

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.

The following code fragment illustrates this issue using a pattern that
is sometimes used in manual reference counting.

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

As described, instead, you can use a __block qualifier and set
the myController variable to nil in the completion handler:

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

Alternatively, you can use a temporary __weak variable. The following
example illustrates a simple implementation:

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

For non-trivial cycles, however, you should use:

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

In some cases you can use __unsafe_unretained if the class
isn’t __weak compatible. This can, however, become impractical for
nontrivial cycles because it can be hard or impossible to validate that
the__unsafe_unretained pointer is still valid and still points to the
same object in question.

ARC Uses a New Statement to Manage Autorelease Pools

Using ARC, you cannot manage autorelease pools directly using
the NSAutoreleasePool class. Instead, you
use @autoreleasepool blocks:

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

This simple structure allows the compiler to reason about the reference
count state. On entry, an autorelease pool is pushed. On normal exit
(break, return, goto, fall-through, and so on) the autorelease pool is
popped. For compatibility with existing code, if exit is due to an
exception, the autorelease pool is not popped.

This syntax is available in all Objective-C modes. It is more efficient
than using the NSAutoreleasePool class; you are therefore encouraged
to adopt it in place of using the NSAutoreleasePool.

Patterns for Managing Outlets Become Consistent Across Platforms

The patterns for declaring outlets in
iOS and OS X change with ARC and become consistent across both
platforms. The pattern you should typically adopt is: outlets should
be weak, except for those from File’s Owner to top-level objects in a
nib file (or a storyboard scene) which should be strong.

Full details are given in “Nib
Files” in Resource

Stack Variables Are Initialized with nil

Using ARC, strong, weak, and autoreleasing stack variables are now
implicitly initialized with nil. For example:

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

will log null for the value of name rather than perhaps crashing.

Use Compiler Flags to Enable and Disable ARC

You enable ARC using a new -fobjc-arc compiler flag. 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. 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.

ARC is supported in Xcode 4.2 and later OS X v10.6 and later (64-bit
applications) and for iOS 4 and later. Weak references are not supported
in OS X v10.6 and iOS 4. There is no ARC support in Xcode 4.1 and

Managing Toll-Free Bridging

In many Cocoa applications, you need to use Core Foundation-style
objects, whether from the Core Foundation framework itself (such
as CFArrayRef or CFMutableDictionaryRef) or from frameworks that
adopt Core Foundation conventions such as Core Graphics (you might use
types like CGColorSpaceRef and CGGradientRef).

The compiler does not automatically manage the lifetimes of Core
Foundation objects; you must call CFRetain and CFRelease (or the
corresponding type-specific variants) as dictated by the Core Foundation
memory management rules (see Memory Management Programming Guide for

If you cast between Objective-C and Core Foundation-style objects, you
need to tell the compiler about the ownership semantics of the object
using either a cast (defined in objc/runtime.h) or a Core
Foundation-style macro (defined in NSObject.h):

  • __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 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.

For example, if you had code like this:

- (void)logFirstNameOfPerson:(ABRecordRef)person {
    NSString *name = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
    NSLog(@"Person's first name: %@", name);
    [name release];

you could replace it with:

- (void)logFirstNameOfPerson:(ABRecordRef)person {
    NSString *name = (NSString *)CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
    NSLog(@"Person's first name: %@", name);

The Compiler Handles CF Objects Returned From Cocoa Methods

The compiler understands Objective-C methods that return Core Foundation
types follow the historical Cocoa naming conventions (see Advanced
Memory Management Programming
For example, the compiler knows that, in iOS, the CGColor returned by
the CGColor method of UIColor is not owned. You must still use an
appropriate type cast, as illustrated by this example:

NSMutableArray *colors = [NSMutableArray arrayWithObject:(id)[[UIColor darkGrayColor] CGColor]];
[colors addObject:(id)[[UIColor lightGrayColor] CGColor]];

Cast Function Parameters Using Ownership Keywords

When you cast between Objective-C and Core Foundation objects in
function calls, you need to tell the compiler about the ownership
semantics of the passed object. The ownership rules for Core Foundation
objects are those specified in the Core Foundation memory management
rules (see Memory Management Programming Guide for Core
rules for Objective-C objects are specified in Advanced Memory
Management Programming

In the following code fragment, the array passed to
the CGGradientCreateWithColors function requires an appropriate cast.
Ownership of the object returned by arrayWithObjects: is not passed to
the function, thus the cast is __bridge.

NSArray *colors = <#An array of colors#>;
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);

The code fragment is shown in context in the following method
implementation. Notice also the use of Core Foundation memory management
functions where dictated by the Core Foundation memory management rules.

- (void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
    CGFloat locations[2] = {0.0, 1.0};
    NSMutableArray *colors = [NSMutableArray arrayWithObject:(id)[[UIColor darkGrayColor] CGColor]];
    [colors addObject:(id)[[UIColor lightGrayColor] CGColor]];
    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.

Common Issues While Converting a Project

When migrating existing projects, you are likely to run into various
issues. Here are some common issues, together with solutions.

You can’t invoke retainrelease, or autorelease.
This is a feature. You also can’t write:

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

You can’t invoke dealloc.
You typically invoke dealloc if you are implementing a singleton or
replacing an object in an init methods. For singletons, use the shared
instance pattern. In init methods, you don’t have to
call deallocanymore, because the object will be freed when you
overwrite self.

You can’t use NSAutoreleasePool objects.
Use the new @autoreleasepool{} construct instead. This forces a block
structure on your autorelease pool, and is about six times faster
than NSAutoreleasePool@autoreleasepool even works in non-ARC code.
Because @autoreleasepool is so much faster than NSAutoreleasePool,
many old “performance hacks” can simply be replaced with
unconditional @autoreleasepool.

The migrator handles simple uses of NSAutoreleasePool, but it can’t
handle complex conditional cases, or cases where a variable is defined
inside the body of the new @autoreleasepool and used after it.

ARC requires you to assign the result of [super init] to self in init methods.
The following is invalid in ARC init methods:

[super init];

The simple fix is to change it to:

self = [super init];

The proper fix is to do that, and check the result for nil before

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

You can’t implement custom retain or release methods.
Implementing custom retain or release methods breaks weak pointers.
There are several common reasons for wanting to provide custom

  • Performance.

    Please don’t do this any more; the implementation
    of retain and release for NSObject is much faster now. If you
    still find problems, please file bugs.

  • To implement a custom weak pointer system.

    Use __weak instead.

  • To implement singleton class.

    Use the shared instance pattern instead. Alternatively, use class
    instead of instance methods, which avoids having to allocate the
    object at all.

“Assigned” instance variables become strong.
Before ARC, instance variables were non-owning references—directly
assigning an object to an instance variable did not extend the lifetime
of the object. To make a property strong, you usually implemented or
synthesized accessor methods that invoked appropriate memory management
methods; in contrast, you may have implemented accessor methods like
those shown in the following example to maintain a weak property.

@interface MyClass : Superclass {
    id thing; // Weak reference.
// ...
@implementation MyClass
- (id)thing {
    return thing;
- (void)setThing:(id)newThing {
    thing = newThing;
// ...

With ARC, instance variables are strong references by default—assigning
an object to an instance variable directly does extend the lifetime of
the object. The migration tool is not able to determine when an instance
variable is intended to be weak. To maintain the same behavior as
before, you must mark the instance variable as being weak, or use a
declared property.

@interface MyClass : Superclass {
    id __weak thing;
// ...
@implementation MyClass
- (id)thing {
    return thing;
- (void)setThing:(id)newThing {
    thing = newThing;
// ...


@interface MyClass : Superclass
@property (weak) id thing;
// ...
@implementation MyClass
@synthesize thing;
// ...

You can’t use strong ids in C structures.
For example, the following code won’t compile:

struct X { id x; float y; };

This is because x defaults to strongly retained and the compiler can’t
safely synthesize all the code required to make it work correctly. For
example, if you pass a pointer to one of these structures through some
code that ends up doing a free, each id would have to be released
before the struct is freed. The compiler cannot reliably do this, so
strong ids in structures are disallowed completely in ARC mode. There
are a few possible solutions:

  1. Use Objective-C objects instead of structs.

    This is considered to be best practice anyway.

  2. If using Objective-C objects is sub-optimal, (maybe you want a dense
    array of these structs) then consider using a void* instead.

    This requires the use of the explicit casts, described below.

  3. Mark the object reference as __unsafe_unretained.

    This approach may be useful for the semi-common patterns like this:

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

    You declare the structure as:

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

    This may be problematic and is unsafe if the object could be
    released out from under the pointer, but it is very useful for
    things that are known to be around forever like constant string

You can’t directly cast between id and void* (including Core Foundation types).
This is discussed in greater detail in “Managing Toll-Free

Frequently Asked Questions

How do I think about ARC? Where does it put the retains/releases?

Try to stop thinking about where the retain/release calls are put and
think about your application algorithms instead. Think about “strong and
weak” pointers in your objects, about object ownership, and about
possible retain cycles.

Do I still need to write dealloc methods for my objects?


Because ARC does not automate malloc/free, management of the
lifetime of Core Foundation objects, file descriptors, and so on, you
still free such resources by writing a dealloc method.

You do not have to (indeed cannot) release instance variables, but you
may need to invoke [self setDelegate:nil] on system classes and other
code that isn’t compiled using ARC.

dealloc methods in ARC do not require—or allow—a call
to [super dealloc]; the chaining to super is handled and enforced by
the runtime.

Are retain cycles still possible in ARC?


ARC automates retain/release, and inherits the issue of retain cycles.
Fortunately, code migrated to ARC rarely starts leaking, because
properties already declare whether the properties are retaining or not.

How do blocks work in ARC?

Blocks “just work” when you pass blocks up the stack in ARC mode, such
as in a return. You don’t have to call Block Copy any more. You still
need to use [^{} copy] when passing “down” the stack
intoarrayWithObjects: and other methods that do a retain.

The one thing to be aware of is that NSString * __block myString is
retained in ARC mode, not a possibly dangling pointer. To get the
previous behavior,
use __block NSString * __unsafe_unretained myString or (better still)
use __block NSString * __weak myString.

Can I develop applications for OS X with ARC using Snow Leopard?

No. The Snow Leopard version of Xcode 4.2 doesn’t support ARC at all on
OS X, because it doesn’t include the 10.7 SDK. Xcode 4.2 for Snow
Leopard does support ARC for iOS though, and Xcode 4.2 for Lion
supports both OS X and iOS. This means you need a Lion system to build
an ARC application that runs on Snow Leopard.

Can I create a C array of retained pointers under ARC?

Yes, you can, as illustrated by this example:

// 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];
// When you're done, set each entry to nil to tell ARC to release the object.
for (int i = 0; i < entries; i++) {
     dynamicArray[i] = nil;

There are a number of aspects to note:

  • You will need to write __strong SomeClass ** in some cases,
    because the default is __autoreleasing SomeClass **.

  • The allocated memory must be zero-filled.

  • You must set each element to nil before freeing the array
    (memset or bzero will not work).

  • You should avoid memcpy or realloc.

Is ARC slow?

It depends on what you’re measuring, but generally “no.” The compiler
efficiently eliminates many extraneous retain/release calls and much
effort has been invested in speeding up the Objective-C runtime in
general. In particular, the common “return a retain/autoreleased object”
pattern is much faster and does not actually put the object into the
autorelease pool, when the caller of the method is ARC code.

One issue to be aware of is that the optimizer is not run in common
debug configurations, so expect to see a lot
more retain/release traffic at -O0 than at -Os.

Does ARC work in ObjC++ mode?

Yes. You can even put strong/weak ids in classes and containers. The
ARC compiler synthesizes retain/release logic in copy constructors
and destructors etc to make this work.

Which classes don’t support weak references?

You cannot currently create weak references to instances of the
following classes:

and NSTextView.

Note: In addition, in OS X v10.7, you cannot create weak references
to instances
of NSFontManagerNSFontPanelNSImageNSTableCellViewNSViewControllerNSWindow,
and NSWindowController. In addition, in OS X v10.7 no classes in the
AV Foundation framework support weak references.


For declared properties, you should use assign instead of weak; for
variables you should use __unsafe_unretained instead of __weak.

In addition, you cannot create weak references from instances
of NSHashTableNSMapTable, or NSPointerArray under ARC.

What do I have to do when subclassing NSCell or another class that
uses NSCopyObject?

Nothing special. ARC takes care of cases where you had to previously add
extra retains explicitly. With ARC, all copy methods should just copy
over the instance variables.

Can I opt out of ARC for specific files?


When you migrate a project to use ARC, the -fobjc-arc compiler flag is
set as the default for all Objective-C source files. You can disable ARC
for a specific class using the -fno-objc-arc compiler flag for that
class. In Xcode, in the target Build Phases tab, open the Compile
Sources group to reveal the source file list. Double-click the file for
which you want to set the flag, enter -fno-objc-arc in the pop-up
panel, then click Done.

Is GC (Garbage Collection) deprecated on the Mac?

Garbage collection is deprecated in OS X Mountain Lion v10.8, and will
be removed in a future version of OS X. Automatic Reference Counting is
the recommended replacement technology. To aid in migrating existing
applications, the ARC migration tool in Xcode 4.3 and later supports
migration of garbage collected OS X applications to ARC.

Note: For apps targeting the Mac App Store, Apple strongly
recommends you replace garbage collection with ARC as soon as feasible,
because Mac App Store guidelines (see App Store Review Guidelines for
Mac Apps
) prohibit the use of deprecated technologies.


电子邮件地址不会被公开。 必填项已用*标注