| I l@ve RuBoard |
|
1.12 Memory ManagementThe liveness of an object—whether or not it is referenced by other objects currently in use—is inherently a global property. This means that keeping track of object usage tempts you to breach the encapsulation and modularity of your program. There are several approaches you can use with Objective-C to help manage object lifecycles:
The programming tools and libraries you use may constrain you toward or away from some strategies. For example, the Cocoa class library uses reference counting; if your code uses Cocoa objects it will have to be written to manage those objects with reference counting, even if your own objects use a different mechanism. 1.12.1 Manual Memory ManagementYou can explicitly release the memory held by an object by calling its -free method (if it inherits from Object) or its -dealloc method (if it inherits from NSObject). It will be your responsibility to ensure that your program no longer needs the object. In classes you write, the deallocation method should release any objects managed by the receiver, as well as any other kinds of resources (such as network sockets) the receiver holds. As with deciding to deallocate the receiver itself, it is your responsibility to ensure that your program no longer needs the objects the receiver will release. This is difficult enough that automatic management systems are becoming more prevalent. 1.12.2 Reference CountingThe Cocoa framework supports reference counting: a technique that associates with an object a count that describes how many references there are to the object in other code. When this count is positive, the object is in use; when the count reaches zero the object can be discarded and its memory reclaimed. The count doesn't specify the users of the object. When an object has a reference count of one it means some other code uses it. If you release one object from memory but forget that it was maintaining a counted reference to another object, the runtime will never notice a discrepancy. For reference counting to be effective you must observe some conventions or design patterns when using its methods. This section gives guidelines for using the reference counting methods.
1.12.2.1 Maintaining an object's reference countCocoa provides four root class methods, -retain, -release, -autorelease, and -retainCount, for using reference counting. (They are documented in Section 1.10.) You don't have to override the methods, just inherit from NSObject and use them. An object's reference count changes in the following ways:
These rules lead to the following rule of thumb:
(The releases outnumber the retains because an object's reference count starts at one, not zero.) Using reference counting correctly calls for coordination when passing objects as parameters between scopes or threads. You need to know when the methods are called for you implicitly, and when to call them yourself. The following sections describe some of the most common situations and how to handle them. 1.12.2.2 Creating a new objectWhen you create the object yourself, by using an +alloc, -copy, or -mutableCopy method, you've already implicitly called -retain. The question then is when to release the object. Following are some common alternatives:
1.12.2.3 Receiving an object from another scopeYou get an object as a parameter in a method, or from a class method whose name starts with the class name. In both cases, some other code is the owner, and may call -release based on criteria hidden from you. How you manage the object's reference depends on how you use it:
1.12.2.4 Returning an already-stored objectYou are returning a value you didn't just create, for example, in a method that returns a field (a "getter"). In this case, you have the following choices for returning the object:
1.12.2.5 Replacing an already-stored objectYou are provided with a new object to replace an existing one, for example, in a method that sets a field (a "setter"). There are a few equally safe solutions:
For example, to use the third approach for a setter for a field named ownedObj, your setter will look like: -(void )setOwnedObj :(id )newObj {
[newObj retain];
[ownedObj release];
ownedObj = newObj ;
}
Don't call -copy instead of -retain in a setter. It is safe as far as memory usage goes, but prevents your caller from sharing the value; by contrast, when you use -retain a caller can copy the new object explicitly and pass the copy to the setter. 1.12.2.6 Deallocating an objectWhen a call to -release sets your object's reference count to zero, the -release method will also call the object's -dealloc method. In that method, you should release all other objects (e.g., fields) and resources that your object is retaining. If other code that shares those objects is retaining them (as it should), this will be safe. You can make your -dealloc method safer in the face of outside code that may have bugs by calling -autorelease on your retained objects. This leaves the autoreleased objects still available until the current call stack finishes. However, it is probably a design mistake if code remaining in the call stack depends on these objects, and using -autorelease may just hide this rather than solve it. 1.12.2.7 Retain cyclesReference counting can break down when there is a closed loop in the graph of object references. In this case a group of mutually referent objects may be garbage (i.e., unreachable from your program) but with positive reference counts. You don't have to avoid such structures, but make sure that you only apply the counting in one direction. When two objects refer to each other, decide which is the "owner" and let it retain the other object, but not vice versa. 1.12.3 Garbage CollectionGarbage collection is a memory management technique that fully automates the release and reuse of object memory. A garbage collector keeps track of which objects are reachable from running code; unreachable objects (those with no references, direct or indirect) are released. The gcc compiler emits code that can be linked with the Boehm garbage collector (an open source garbage collector for C-based languages). This library augments the standard C function malloc( ) with code that sets up tracking information for object pointers, and replaces the function free( ) with an empty body. The garbage collector runs concurrently in your program, releasing objects only when they are no longer reachable by executing code. The Boehm garbage collector will even correctly deal with cycles of mutually-referring but unreachable objects. To use the garbage collector, you download and compile it as a library for your platform, and link it with your Objective-C program. You can get the code, and instructions on how to install it, at http://www.hpl.hp.com/personal/Hans_Boehm/gc/.
|
| I l@ve RuBoard |
|