天天看點

ARC Basics 1

Rules and Conventions for Using ARC

As mentioned, ARC greatly simplifies memory management with respect to the MRR method. As a result, there are different sets of rules for object memory management under ARC. These rules are as follows:

  • You cannot send retain, retainCount, release, autorelease, or deallocmessages. ARC forbids programmatic control of an object life cycle and automatically inserts these messages where required during compilation. This includes@selector(retain), @selector(release), and related methods. You mayimplement a dealloc method if you need to manage resources other than instance variables. ARC automatically creates a dealloc method in your classes (if not provided) to release the objects it owns, and invokes [super dealloc] in your implementation(s) of the dealloc method.
  • You can’t cast directly between id and (void *) types. ARC only manages Objective-C objects and blocks, thus the compiler needs to know the types of the objects it is processing. Because a pointer to void (void *) is a generic pointer type that can be converted to any other pointer type (even those that are not Objective-C pointer types), this restriction is necessary. This scenario is common when casting between Foundation Framework objects and Core Foundation types (Core Foundation is an Apple software library that provides C-language APIs). A set of APIs is provided for ownership transfer of variables between ARC and non-ARC environments.
  • Autorelease pool blocks should be used to perform ARC-managed autorelease of objects.
  • You cannot call the Foundation Framework functions NSAllocateObject andNSDeallocateObject. These functions provide the capability to allocate and deallocate memory for an object in a specific memory zone. Because zone-based memory is no longer supported, these functions cannot be used.
  • You cannot use object pointers in C structures (structs). ARC does not perform memory management for dynamically allocated C structures, thus the compiler cannot determine where to insert the necessary retain and release messages.
  • You cannot use memory zones (NSZone). As mentioned, zone-based memory is no longer supported.
  • To properly cooperate with non-ARC code, you cannot create a method or a declared property (unless you explicitly choose a different getter) that begins with “copy”.
  • By default, ARC is not exception-safe: it does not end the lifetime of __strongvariables whose scope is abnormally terminated by an exception, and it does not perform releases of objects that would occur at the end of a full-expression if that full-expression throws an exception. The compiler option -fobjc-arc-exceptionscan be used to enable exception handling for ARC code. ARC does end the lifetimes of weak references when an exception terminates their scope, unless exceptions are disabled in the compiler.

ARC Lifetime Qualifiers

There are a set of ARC-specific qualifiers that declare the object lifetime for both regular variables and properties. The following are those for regular variables:

  • __strong: Any object created using alloc / init is retained for the lifetime of its current scope. This is the default setting for regular variables. The “current scope” usually means the braces in which the variable is declared (a method, for loop, ifblock, etc.)
  • __weak: The object can be destroyed at anytime. This is only useful if the object is somehow strongly referenced somewhere else. When destroyed, a variable with__weak is set to nil.
  • __unsafe_unretained: This is just like __weak but the pointer is not set to nilwhen the object is deallocated. Instead, the pointer is left dangling (i.e., it no longer points to anything useful).
  • __autoreleasing: Not to be confused with calling autorelease on an object before returning it from a method, this is used for passing objects by reference.

When using ARC lifetime qualifiers to declare variables for Objective-C objects, the correct syntax is

ClassName *qualifier varName;      

ClassName is name/type of the class (OrderEntry, etc.), qualifier is the ARC lifetime qualifier (as previously listed), and varName is the name of the variable. If no qualifier is specified, the default is__strong. The ARC-specific lifetime qualifiers for properties are as follows:

  • strong: The strong attribute is equivalent to the retain attribute (the complete list of property attributes is provided in Appendix A).
  • weak: The weak attribute is similar to the assign attribute, except that if the affected property instance is deallocated, its instance variable is set to nil.

Under ARC, strong is the default ownership attribute for object-type properties.

Roundup

  • At runtime, an Objective-C program creates objects (via the NSObject allocmethod) stored in dynamically allocated memory referred to as the program heap. Dynamic object creation implies the need for memory management, because objects created on the heap never go out of scope. Typical results of incorrect or no memory management include memory leaks and dangling pointers.
  • Objective-C memory management is implemented using reference counting, a technique whereby unique references to an object are used to determine whether or not an object is still in use. If an object’s reference count drops to zero, it is considered no longer in use and its memory is deallocated by the runtime system.
  • The Apple Objective-C development environment provides two mechanisms that can be used for memory management: Manual Retain-Release (MRR) and Automatic Reference Counting (ARC).
  • With MRR, you write your code to explicitly manage the life cycle of objects, obtaining an ownership interest in objects that you create/need to use, and releasing that ownership interest when you no longer need the object(s).
  • ARC employs the same reference counting model as MRR, but utilizes the compiler to manage the object life cycle. At program compilation, the compiler analyzes the source code, determines the life cycle requirements for dynamically created objects, and then automatically inserts retain and release messages where necessary in the compiled code.
  • ARC is augmented with new object lifetime qualifiers that are used to explicitly declare the lifetime of object variables and properties, and also includes functionality (weak references) that can be used to prevent circular references in object graphs.
  • ARC can be used across a project or on a per-file basis, thereby enabling code that uses ARC to still work with existing code that is not ARC-compliant. Apple also provides a conversion tool for migrating existing Objective-C code to ARC. ARC is the recommended tool for memory management on all new Objective-C projects.

1.

Claiming Ownership Interest in Objects

Your Objective-C code takes an ownership interest in any object that it creates using any method that has a name beginning with alloc, new, copy, or mutableCopy.

2.

Releasing Ownership Interest in Objects

As mentioned previously, ARC prohibits programmatic use of the release, autorelease, dealloc, or related messages on an object. Your code gives up ownership interest in an object when it performs any of the following: 1) variable reassignment, 2) nil assignment, or 3) its owner is deallocated.

3. In sum, when an object is retrieved via a property getter, ARC sends retain and autoreleasemessages to the object to prevent it from being deallocated. This explains why the OrderItem objects were deallocated at the end of the autorelease pool block, and not when the parent (OrderEntry) objects were deallocated.

繼續閱讀