|
|
|
|
|
|
|
| PATH |

There are times when you don't want a received object to
be disposed of; for example, you may need to cache the object in
an instance variable. In this case, only you know when the object
is no longer needed, so you need the power to ensure that the object
is not disposed of while you are still using it. You do this with
the retain method, which stays the effect of
a pending autorelease (or preempts a later release or autorelease message).
By retaining an object you ensure that it won't be deallocated
until you're done with it. For example, if your object allows
its main Sprocket to be set, you might want to retain that Sprocket
like this:
- (void)setMainSprocket:(Sprocket *)newSprocket
{
[mainSprocket autorelease];
mainSprocket = [newSprocket retain]; /* Claim the new Sprocket. */
return;
}Now, setMainSprocket: might get invoked
with a Sprocket that the invoker intends to keep around, which means
your object would be sharing the Sprocket with that other object.
If that object changes the Sprocket, your object's main Sprocket
changes. You might want that, but if your Thingamajig needs to have
its own Sprocket, the method should make a private copy:
- (void)setMainSprocket:(Sprocket *)newSprocket
{
[mainSprocket autorelease];
mainSprocket = [newSprocket copy]; /* Get a private copy. */
return;
}Note that both of these methods autorelease the original main sprocket, so they don't need to check that the original main sprocket and the new one are the same. If they simply released the original when it was the same as the new one, that sprocket would be released and possibly deallocated, causing an error as soon as it was retained or copied. Although they could store the old main sprocket and release it later, that kind of code tends to be slightly more complex. For example:
- (void)setMainSprocket:(Sprocket *)newSprocket
{
Sprocket *oldSprocket = mainSprocket;
mainSprocket = [newSprocket copy];
[oldSprocket release];
return;
}In general, you retain all objects that you create. However, in some cases you may have two objects with cyclical references; that is, each object contains an instance variable that refers to the other object. For example, consider a text program with the object relationships shown in Figure 6-1 . The Document object creates a Page object for each page in the document. Each Page object has an instance variable that keeps track of which document it's in. If the Document object retained the Page object and the Page object retained the Document object, neither object would ever be released. The Document's reference count can't become 0 until the Page object is released, and the Page object won't be released until the Document object is deallocated.
The solution to the problem of retain cycles is that the "parent" object should retain its "children," but that the children should not retain their parents. So, in the following figure the document object retains its page objects but the page object does not retain the document object.
Figure 6-1 Retaining Objects

© 2001 Apple Computer, Inc.
|
|
|
Contact Us | Privacy Notice Copyright © 2000 Apple Computer, Inc. All rights reserved. 1-800-MY-APPLE |