Automatic Reference Counting

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

In Objective-C and Swift programming, Automatic Reference Counting (ARC) is a memory management enhancement where the burden of keeping track of an object's reference count is lifted from the programmer to the compiler.[1] In traditional Objective-C, the programmer would send retain and release messages to objects in order 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 programmer 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 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 10.6 "Snow Leopard" or later, and iOS 4.0 or later. Mac OS X 10.7 "Lion" 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 using ARC in Objective C[edit]

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

  • You 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
}
  • You cannot cast directly between id and void *.[9] This includes casting between Foundation objects and Core Foundation objects.
You must use special casts, or calls to special functions, to tell the compiler more information about the 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;
}
  • You cannot use NSAutoreleasePool objects.[9]
You 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
        }
    }
}
  • You cannot call the functions NSAllocateObject and NSDeallocateObject[9]
  • You cannot use object pointers in C structures (structs)[9]
  • You cannot use memory zones (NSZone)[9]
  • To properly cooperate with non-ARC code, you also cannot create a method or a declared property (unless you explicitly choose a different getter) that begins with "copy".[9]

Property Declarations[edit]

ARC introduces some new property declaration attributes, some of them replacing 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 begins deallocation. 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 when an object is being deallocated to set all possible weak references to it to nil manually. 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 10.7 "Lion" 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 ARC[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.

ARC in Swift[edit]

Swift uses ARC to manage memory. To allow the programmer to prevent strong reference cycles from occurring, Swift provides the weak and unowned keywords. 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. The programmer can indicate which self references should be treated as weak or unowned using 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. http://arstechnica.com. 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 1014. 
  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. http://clang.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

External links[edit]