Automatic reference counting


Published on

ARC stands for Automatic Reference Counting. Apple has introduced ARC in IOS 5 to free developers from managing memory manually and focus on business logic of applications.

Published in: Education
1 Comment
  • Sorry but your page comparing ARC to GC is full of misinformation, as most pages on the web at the moment do which make the same comparison. (It's a bunch of misinformation (probably unintentionally) ignited by Apple through the touting of their newly implemented ARC as being better than their GC (yes, *their* GC sucked, but not the idea of GC in general or other GC implementations), and this misinformation seems to have been propagated through the web by Apple fanboys, possibly in part due to getting repeatedly trolled about the lack of GC on their platform, so they wanted to backlash? Whatever, stupid smartphone wars.)

    First of all, ARC does have a run-time penalty, as does manual retain-release. The refcount of an object needs to be updated through an *atomic* operation (thread-safe/locked, quite expensive) in many/most cases where a pointer to an object is created or destroyed (including for instance calling a function or method and passing it an object, imagine how common this is). This overhead spans permanently over program execution and is the reason why decades of academia and benchmarks have concluded refcounting to be an inferior technique in terms of CPU efficiency. Less importantly, the reference counts need to be kept somewhere, so you have a small memory overhead for every object.

    GC does not *require* a separate thread. To the contrary, it usually works by 'stopping the world' (pausing threads) and doing its work, then resuming threads. (Don't worry, these pauses can be made to be so short that a human doesn't notice it in an interactive application. Besides, CoreAnimation runs in its own thread and would likely be unaffected by e.g. a GC stopping the main thread, so you won't get animation jitter even if the GC does pause for longer times.) Concurrent GCs running in separate threads exist too, they're one of the *many* options you have.

    ARC is 'similar' to GC in that you don't have to retain/release or alloc/free, but you do have to care about your object graph and make sure that there are clear 'owner' semantics with back-links in your graph being weak references. This is very intuitive in many cases, highly painful in others. The biggest problem in my experience is with 'block' objects (first-class closures) in Objective-C, where it's very usual to have a block that references an object, but also belongs to that object. Like myObject.fooHandler = ^{ doSomethingWith(myObject); }; // Retain cycle! You're leaking memory now! (The block holds a reference to 'myObject' in the function-call, and the block itself belongs to myObject. You need some boilerplate code to make a weak-reference to myObject and only use that in the block.)

    ARC *can* be predictable about releasing objects. If it is so, which it is in the most naive implementation, it means that when you release the head of a deep object graph, ARC goes through the whole graph and decrements the refcounts and deallocates all objects in the graph. This means that simply a variable going out of scope can cause a deeply recursive deallocation, and you effectively have a little 'pause' in your program during that. Sounds familiar? Yeah, the same pause you keep complaining about in garbage collection! (And many GCs actually solve that problem, through incremental and/or generational scanning.) The solution against this is not to guarantee immediate deallocation, and instead put objects in some to-be-deallocated list which is traversed later; in this case you lose the deterministic/immediate deallocation characteristic you like so much.

    All in all, refcounting has many problems. ARC seems to work well in iOS development except when retain cycles (or the boilerplate code you need to avoid them) bite your ass, and I don't know how much CPU overhead ARC causes. A good GC implementation could probably do better, but I have a feeling that all of Apple's libraries are so deeply tied into refcounting as of now, that it's just really hard to make a good GC for Objective-C/iOS. Otherwise I don't know why they went with ARC.
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Automatic reference counting

  2. 2. AT A GLANCE• Objective C provides two methods of memory management • MRR (manual – retain – release) • Implemented through a model known as Reference counting, that NSObject class provides • ARC (automatic reference counting) • It uses the same reference counting system as MRR, but it inserts the appropriate memory management method calls for you at compile-time
  3. 3. MANUAL REFERENCE COUNTING• Just to help you appreciate ARC... • Retain: +1 retain count (claim ownership) • Release: -1 retain count (revoke ownership) • Autorelease: Ownership is transferred to latest autorelease pool on the current thread • When retain count reaches 0, the object is deleted.• With ARC you ignore all of this
  5. 5. WHAT IS ARC?• Automatic Reference Counting• Never need to call -release or –autorelease• More efficient than garbage collection• No more memory leaks! • Doesn’t handle retain loops• Memory management a job of Compiler• Includes a weak reference system (Lion/iOS 5.0)• ARC code works with non-ARC code as well• Xcode 4.2+ only
  6. 6. NEW RULES• You cannot explicitly invoke dealloc, or implement or invoke retain, release, retainCount, 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 CFRetain, CFRelease, and other related functions with Core Foundation-style objects
  7. 7. NEW RULES• 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.
  8. 8. NEW RULES• You cannot use NSAutoreleasePool objects. • ARC provides @autoreleasepool blocks instead. These have an advantage of being more efficient than NSAutoreleasePool. @autoreleasepool { // Code, such as a loop that creates a large number of temporary objects. }• You cannot use memory zones. • There is no need to use NSZone any more—they are ignored by the modern Objective-C runtime anyway.
  9. 9. NEW RULESTo allow interoperation with manual retain-releasecode, 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: // Wont work: @property NSString *newTitle; // Works: @property (getter=theNewTitle) NSString *newTitle;
  10. 10. 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). Judicious use of weak relationships will help to ensure you don‘t create cycles.
  11. 11. PROPERTY ATTRIBUTESThe keywords weak and strong are introduced asnew declared property attributes, as shown in thefollowing 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.
  12. 12. WEAK REFERENCING• Weak reference doesn’t increment retain count• Weak reference is nilled when the object is dealloc’d• Adds some overhead due to bookkeeping• Great for delegates • @property(nonatomic, weak) id delegate;• iOS 5.0+
  13. 13. VARIABLE QUALIFIERS• __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.
  14. 14. USING QUALIFIERS• 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;
  15. 15. IBOUTLETS• Weak reference: • Used only with non-top-level IBOutlets • Automatically nils IBOutlet in low memory condition • Requires some extra overhead• Strong reference: • Must be used for top-level IBOutlets • May be used for non-top-level IBOutlets • Manually nil IBOutlet in -viewDidUnload
  16. 16. AVOID STRONG REFERENCE CYCLESYou can use lifetime qualifiers to avoid strong reference cycles. Forexample, typically if you have a graph of objects arranged in a parent-child hierarchy and parents need to refer to their children and viceversa, then you make the parent-to-child relationship strong and thechild-to-parent relationship weak.
  17. 17. BRIDGING• __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.• 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.
  18. 18. ARC VS GC• ARC != garbage collection. There is no run time penalty, it is done at compile time.• GC require a separate thread to collect garbage and utilize RAM and CPU resources.• ARC is similar to GC in that you dont have to manually retain or release objects.• ARC does not handles ‗ReferenceCycles‘ where as GC handles it.• ARC is predictable about releasing objects where as GC is not as much.
  19. 19. ADVANTAGES OF ARC• It is faster than your old code. It is safer than your old code. It is easier than your old code.• It is not garbage collection. It has no GC runtime cost.• The compiler inserts retains and releases in all the places you should have anyway. But its smarter than you and can optimize out the ones that arent actually needed• Apple is suggestin ARC due to ease and performance, so in future projects ARC projects will dominate.• The benefit is a significant degree of protection from common memory management mistakes.• ARC is to minimize the amount of routine memory mgmt code we have to write, letting us focus the business logic of an app.
  20. 20. ADVANTAGES OF ARC• To conclude: ARC is NOT a free pass to be mindless about memory; it is a tool to help humans avoid repetitive tasks, that cause stress and are prone to error, therefore better delegated to a machine (the compiler, in this case).
  21. 21. DOWNSIDE OF ARC• If youre a long-time ObjC developer, you will twitch for about a week when you see ARC code.• There is some (very) small complications in bridging to Core Foundation code.• ARC will not work at all on iPhoneOS 3 or Mac OS X 10.5 or e• __weak pointers do not work correctly on iOS 4 or Mac OS X 10.6, but fairly easy to work around. __weak pointers are great, but theyre not the #1 selling point of ARC.
  22. 22. DISABLING ARC• ARC can be disabled on a file-level.• Project file > Main target > Build phases > Compile sources > Add compiler flag “-fno-objc-arc”• If ARC is not on by default, it can be turned on manually with “-fobjc-arc”
  23. 23. WHAT ABOUT C?• ARC does not manage memory for C• You must call free() for every malloc() • Core Foundation objects use CFRelease()• Toll-free bridging requires an extra keyword
  24. 24. CONVERSION TO ARCWe are going to convert the Artists app to ARC.Basically this means we‘ll just get rid of all the calls toretain, release, and autorelease, but we‘ll also runinto a few situations that require special attention. • There are three things you can do to make your app ARC- compatible: • Xcode has an automatic conversion tool that can migrate your source files. • You can convert the files by hand. • You can disable ARC for source files that you do not want to convert. This is useful for third-party libraries that you don‘t feel like messing with.
  25. 25. AUTOMATIC CONVERSION• From Xcode‘s menu, choose EditRefactorConvert to Objective-C ARC.
  26. 26. DEMO
  27. 27. QUESTIONS?
  28. 28. WANT TO LEARN MORE?• About Memory Management •• Memory Management Programming Guide for Core Foundation •• Transitioning to ARC Release Notes •• Beginning ARC in iOS 5 Tutorial Part 1 •• Why ARC over GC •• Friday Q&A 2011-09-30: Automatic Reference Counting •