Automatic Reference Counting
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
The following rules are enforced by the compiler when ARC is turned on:
- Programs cannot call
retain
,release
,retainCount
,autorelease
, ordealloc
.[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
andvoid *
.[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
andNSDeallocateObject
[9] - Programs cannot use object pointers in C structures (
struct
s)[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
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
|
- ^ ARCLite is ARC but without zeroing weak references (used when deploying to a less-capable operating environment than ARC requires).
Zeroing weak references
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
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
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
References
- ^ Siracusa, John. "Automatic Reference Counting". Mac OS X 10.7 Lion: the Ars Technica review. Ars Technica. Retrieved 15 August 2012.
- ^ Cruz, José R.C. "Automatic Reference Counting on iOS". Dr.Dobb's. Retrieved 21 August 2012.
- ^ Kochan, Stephen G. (2011). Programming in Objective-C (4th ed.). Boston, Mass.: Addison-Wesley. p. 408. ISBN 978-0321811905.
- ^ "NSGarbageCollector Class Reference". Mac Developer Library. Apple Inc. 23 July 2012. Retrieved 9 June 2014.
- ^ Hoffman, Kevin (2012). Sams teach yourself Mac OS X Lion app development in 24 hours. Indianapolis, Ind.: Sams. p. 73. ISBN 9780672335815.
- ^ "General". Automatic Reference Counting. LLVM.org. Retrieved 15 August 2012.
- ^ 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.
- ^ "Objective-C Feature Availability Index". Apple, Inc. Retrieved 2013-10-14.
- ^ a b c d e f g h "Transitioning to ARC Release Notes". Retrieved 14 September 2012.
- ^ "What's New in Xcode 4.2 – Automatic Reference Counting". Apple Inc. Retrieved 3 October 2012.
- ^ https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html