Objective C提供了三种内存管理方式:
1. “手工持有-释放”或者MRR
2. “自动引用计数”或者ARC
3. 垃圾回收的方式,此种方式只能在Mac OS下使用,iOS下是不行的
错误的内存管理往往包括两类:
1. 释放或者覆盖正在使用中得数据
2. 不用的数据却不释放,从而导致内存泄露
基本内存管理规则
You own any object you create
You create an object using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, alloc, a target="_self" newObject/a, or mutableCopy).
You can take ownership of an object using retain
A received object is normally guaranteed to remain valid within the method it was received in, and that method may also safely return the object to its invoker. You use retain in two situations: (1) In the implementation of an accessor method or an init method, to take ownership of an object you want to store as a property value; and (2) To prevent an object from being invalidated as a side-effect of some other operation (as explained in Avoid Causing Deallocation of Objects You’re Using).
When you no longer need it, you must relinquish ownership of an object you own
You relinquish ownership of an object by sending it a release message or an autorelease message. In Cocoa terminology, relinquishing ownership of an object is therefore typically referred to as “releasing” an object.
You must not relinquish ownership of an object you do not own
This is just corollary of the previous policy rules, stated explicitly.
You Don’t Own Objects Returned by Reference
You Don’t Own Objects Returned by Reference
Never invoke another object’s dealloc method directly.
You must invoke the superclass’s implementation at the end of your implementation.
You should not tie management of system resources to object lifetimes; see Don’t Use dealloc to Manage Scarce Resources.
When an application terminates, objects may not be sent a dealloc message. Because the process’s memory is automatically cleared on exit, it is more efficient simply to allow the operating system to clean up resources than to invoke all the memory management methods.
Use Accessor Methods to Make Memory Management Easier
- (NSNumber *)count {
return _count;
}
- (void)setCount:(NSNumber *)newCount {
|
[newCount retain];
|
[_count release];
|
// Make the new assignment.
|
_count = newCount;
|
} |
Don’t Use Accessor Methods in Initializer Methods and dealloc
The only places you shouldn’t use accessor methods to set an instance variable are in initializer methods and dealloc.
Use Weak References to Avoid Retain Cycles
Cocoa establishes a convention, therefore, that a “parent” object should maintain strong references to its “children,” and that the children should have weak references to their parents.
Avoid Causing Deallocation of Objects You’re Using
There are occasional exceptions to this rule, primarily falling into one of two categories.
1. When an object is removed from one of the fundamental collection classes.
heisenObject = [array objectAtIndex:n];
|
[array removeObjectAtIndex:n];
|
// heisenObject could now be invalid. |
id parent = <#create a parent object#>;
|
// ...
|
heisenObject = [parent child] ;
|
[parent release]; // Or, for example: self.parent = nil;
|
// heisenObject could now be invalid. |
Don’t Use dealloc to Manage Scarce Resources
Problems may arise if you try to piggy-back resource management on top of dealloc. For example:
- Order dependencies on object graph tear-down.The object graph tear-down mechanism is inherently non-ordered. Although you might typically expect—and get—a particular order, you are introducing fragility. If an object is unexpectedly autoreleased rather than released for example, the tear-down order may change, which may lead to unexpected results.
- Non-reclamation of scarce resources.Memory leaks are bugs that should be fixed, but they are generally not immediately fatal. If scarce resources are not released when you expect them to be released, however, you may run into more serious problems. If your application runs out of file descriptors, for example, the user may not be able to save data.
- Cleanup logic being executed on the wrong thread.If an object is autoreleased at an unexpected time, it will be deallocated on whatever thread’s autorelease pool block it happens to be in. This can easily be fatal for resources that should only be touched from one thread.
Collections Own the Objects They Contain