Automatic Reference Counting

From Wikipedia, the free encyclopedia
Jump to: navigation, search

In computer programming, for the programming languages Objective-C and Swift, automatic reference counting (ARC) is a memory management enhancement where the task of keeping track of reference counting for objects is removed from the programmer and onto the compiler.[1] In standard Objective-C, the programmer would send retain and release messages to objects to mark objects for deallocation or to prevent deallocation.[2] Under ARC, the compiler does this automatically by examining the source code and then adding the retain and release messages in the compiled code.[3]

ARC differs from Cocoa's garbage collection [4] in that there is no background process doing the deallocation of objects.[5] Unlike garbage collection, ARC does not handle reference cycles automatically. It is up to the program to break cycles using weak references.[6]

Apple Inc. delivered a fully featured version of ARC in 2011 for application development on its Mac OS X Lion (10.7) and iOS 5 operating systems.[7] Before that, a limited version of ARC (ARCLite[8]) was supported in Xcode 4.2 or later, Mac OS X Snow Leopard (10.6) or later, and iOS 4.0 or later. Mac OS X Lion (10.7), or iOS 5 is recommended to use all the features, including weak reference support. Apple's Swift language, introduced in 2014, uses ARC for memory management.

Rules when used in Objective-C[edit]

The following rules are enforced by the compiler when ARC is turned on:

  • Programs cannot call retain, release, retainCount, autorelease, or dealloc.[9]
The compiler automatically inserts the correct calls at compile time, including messaging [super dealloc] in an override of dealloc.
Code example without ARC:
- (void)dealloc
{
   [[NSNotificationCenter defaultCenter] removeObserver:self];
   [super dealloc];
}
Code example with ARC:
- (void)dealloc
{
   [[NSNotificationCenter defaultCenter] removeObserver:self];
   // no need to call [super dealloc] here
}
  • Programs cannot cast directly between id and void *.[9] This includes casting between Foundation objects and Core Foundation objects.
Programs must use special casts, or calls to special functions, to tell the compiler more information about an object's lifetime.
Code example without ARC:
- (NSString *)giveMeAString
{
    CFStringRef myString = [self someMethodThatCreatesACFString];
    NSString *newString = (NSString *)myString;
    return [newString autorelease];
}
Code example with ARC and a cast:
- (NSString *)giveMeAString
{
    CFStringRef myString = [self someMethodThatCreatesACFString]; // retain count is 1
    NSString *newString = (__bridge_transfer NSString *)myString; // the ownership has now been transferred into ARC
    return newString;
}
Code example with ARC and a function call:
- (NSString *)giveMeAString
{
    CFStringRef myString = [self someMethodThatCreatesACFString]; // retain count is 1
    NSString *newString = (NSString *)CFBridgingRelease(myString); // the ownership has now been transferred into ARC
    return newString;
}
  • Programs cannot use NSAutoreleasePool objects.[9]
Programs must use the @autoreleasepool syntax. This syntax is now available for all Objective-C modes.
Code example without ARC:
- (void)loopThroughArray:(NSArray *)array
{
    for (id object in array) {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        // create a lot of temporary objects
        [pool drain];
    }
}
Code example with ARC:
- (void)loopThroughArray:(NSArray *)array
{
    for (id object in array) {
        @autoreleasepool {
            // create a lot of temporary objects
        }
    }
}
  • Programs cannot call the functions NSAllocateObject and NSDeallocateObject[9]
  • Programs cannot use object pointers in C structures (structs)[9]
  • Programs cannot use memory zones (NSZone)[9]
  • To properly cooperate with non-ARC code, programs must use no method or declared property (unless explicitly choosing a different getter) that starts with copy.[9]

Property declarations[edit]

ARC introduces some new property declaration attributes, some of which replace the old attributes.

Without ARC With ARC With ARCLite [Note 1]
retain strong
assign (for object types) weak unsafe_unretained
copy
  1. ^ ARCLite is ARC but without zeroing weak references (used when deploying to a less-capable operating environment than ARC requires).

Zeroing weak references[edit]

Zeroing weak references is a feature in Objective-C ARC that automatically clears (sets to nil) weak-reference local variables, instance variables, and declared properties immediately before the object being pointed to starts deallocating. This ensures that the pointer goes to either a valid object or nil, and avoids dangling pointers. Prior to the introduction of this feature, "weak references" referred to references that were not retaining, but were not set to nil when the object they pointed to was deallocated (equivalent to unsafe_unretained in ARC), thus possibly leading to a dangling pointer. The programmer typically had to ensure that all possible weak references to an object were set to nil manually when it was being deallocated. Zeroing weak references obviates the need to do this.

Zeroing weak references are indicated by using the declared property attribute weak or by using the variable attribute __weak.

Zeroing weak references are only available in Mac OS X Lion (10.7) or later and iOS 5 or later, because they require additional support from the Objective-C runtime. However, some OS X classes do not currently support weak references.[9] Code that uses ARC but needs to support versions of the OS older than those above cannot use zeroing weak references, and therefore must use unsafe_unretained weak references. There exists a third-party library called PLWeakCompatibility [1] that allows one to use zeroing weak references even on these older OS versions.

Converting to[edit]

Xcode 4.2 or later provides a way to convert code to ARC.[10] As of Xcode 4.5, it is found by choosing Edit > Refactor > Convert to Objective-C ARC... Although Xcode will automatically convert most code, some code may have to be converted manually. Xcode will inform the developer when more complex use cases arise, such as when a variable is declared inside an autorelease pool and used outside it or when two objects need to be toll-free bridged with special casts.

In Swift[edit]

Swift uses ARC to manage memory. To allow programs to preclude strong reference cycles, Swift provides the keywords weak and unowned. Weak references must be optional variables, since they can change and become nil.

A closure within a class can also create a strong reference cycle by capturing self references. Self references to treat as weak or unowned can be indicated via a capture list.[11]

See also[edit]

References[edit]

  1. ^ Siracusa, John. "Automatic Reference Counting". Mac OS X 10.7 Lion: the Ars Technica review. Ars Technica. Retrieved 15 August 2012. 
  2. ^ Cruz, José R.C. "Automatic Reference Counting on iOS". Dr.Dobb's. Retrieved 21 August 2012. 
  3. ^ Kochan, Stephen G. (2011). Programming in Objective-C (4th ed.). Boston, Mass.: Addison-Wesley. p. 408. ISBN 978-0321811905. 
  4. ^ "NSGarbageCollector Class Reference". Mac Developer Library. Apple Inc. 23 July 2012. Retrieved 9 June 2014. 
  5. ^ Hoffman, Kevin (2012). Sams teach yourself Mac OS X Lion app development in 24 hours. Indianapolis, Ind.: Sams. p. 73. ISBN 9780672335815. 
  6. ^ "General". Automatic Reference Counting. LLVM.org. Retrieved 15 August 2012. 
  7. ^ Sakamoto, Kazuki (2012). Pro Multithreading and Memory Management for iOS and OS X with ARC, Grand Central Dispatch and Blocks. Apress. pp. xii. ISBN 978-1430241164. 
  8. ^ "Objective-C Feature Availability Index". Apple, Inc. Retrieved 2013-10-14. 
  9. ^ a b c d e f g h "Transitioning to ARC Release Notes". Retrieved 14 September 2012. 
  10. ^ "What's New in Xcode 4.2 – Automatic Reference Counting". Apple Inc. Retrieved 3 October 2012. 
  11. ^ https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html

External links[edit]