
Source: Effective Objective-C 2.0
Objective-C uses reference counting for memory management, meaning that every object has a counter that is incremented and decremented. You increment the counter when you want to register your interest in keeping an object alive, and you decrement the counter when you have finished with it.
When an object’s counter reaches 0, the object no longer has anything interested in it and is free to be destroyed.
How Reference Counting Works
retain Increment the retain countrelease Decrement the retain countautorelease Decrement the retain counter later, when the autorelease pool is drained.
An object is always created with a retain count of at least 1. Interest in keeping the object alive is indicated by invoking the retain method.
Own other objects Objects are said to own other objects if they hold a strong reference to them.
1 |
NSMutableArray *array = [[NSMutableArray alloc] init]; |
In Objective-C, a call to alloc will result in the return of an object that is said to be owned by the caller. However, it’s important to note that this doesn’t necessarily mean that the retain count is exactly 1. It might be more, since the implementation of either alloc or initWithInt: may mean that other retains have been made on the object.
You should never do something like this:
1 |
NSMutableArray *array = [[NSMutableArray alloc] init]; |
Memory Management in Property Accessors
If the Property is a strong relationship, the value of the property is retained. A setter accessor for such a property called foo backed by an instance variable called _foom would look like this:
1 |
- (void)setFoo:(id)foo { |
The new valued is retained, and the old value is retained. Then the instance variable is updated to point to the new value. The order is important. If the old value was released before the new value was retained, and the two values are exactly the same, the release would mean that the object could potentially be deallocated prematurely. The subsequent retain could not resurrect the deallocated object, and the instance variable would be a dangling point.
Autorelease Pools
Retain Cycle
The problem is usually solved by using weak reference.
Use ARC to make Reference Counting Easier
1 |
if ([self shouldLogMessage]) { |
Because ARC adds retain, release and autorelease for you, calling memory management method directly under ARC is illegal.
Method-Naming Rules Applied by ARC
A method returning an object returns it owned by the caller if its method name begins with one of the following:
allocnewcopymutableCopy
“Owned by the caller” means that the code calling any of the 4 methods listed is responsible for releasing the returned object.
Memory-Management Semantics of Variables
ARC also handles memory management of local variables and instance variables. By default, every variable is said to hold a strong reference to the object.
The semantics of local and instance variables can be altered through the application of the following qualifiers:
__strong: the default, the value is retained.__unsafe_retain: the value is not retained and is potentially unsafe, as the object may have been deallocated already by the time the variable is used again.__weak: the value is not retained but is safe because it is automatically set to nil, if the current object is ever deallocated.__autorelease: this special qualifier is used when an object is passed by reference to a method. The value is autoreleased on return._
When applied to local variables, the qualifiers are often used to break retain cycles that can be introduced with blocks. A block automatically retains all objects it captures, which can sometimes lead to a retain cycle if an object retaining a block is retained by the block. A __weak local variable can be used to break the retain cycle.
1 |
NSURL *url = [NSURL URLWithString:@"http://www.example.com/"]; |
ARC Handling of Instance Variables
ARC also hands the memory management of instance variables. Doing so requires ARC to automatically generate the required cleanup code during deallocation. Any variables holding
You still need to cleanup any non-Objective-C objects if you have any, such as CoreFoundation objects or heap-allocated memory, with malloc()
1 |
- (void)dealloc { |
Overriding the Memory-Management Methods
Release References and Clean Up Observation State Only in dealloc
A dealloc method looks like this:
1 |
- (void)dealloc { |
Beware of Memory Management with Exception-Safe Code
Use Weak References to Avoid Retain Cycles
Using weak properties is not an excuse to be lazy. You should aim to ensure that weak properties alive when the object need it.
For example, a user interface element having a data source property that it queries to get the data to display. Such a property would usually need to be weak reference. If the data source object was deallocated before the element had finished with it, a weak reference means that it will not crash but won’t display any data.
Use Autorelease Pool Blocks to Reduce High-Memory Waterline
Releasing an object means that its retain count either is decremented immediately through a call to release or is added to an auto-release pool through a call to autorelease. An autorelease pool is used as a collection of objects that will need releasing at some point in the future. When a pool is drained, all the objects in the pool at that time are send the release message.




近期评论