开发者

To Autorelease or Not to Autorelease

In the following code example from the Core Data Programming Guide, NSFetchRequest is created with autorelease while NSSortDescriptor is not created with autorelease. Why wasn't NSSortDescriptor created with autorelease? Is it a matter of preference?

NSManagedObjectContext *moc = [self managedObjectContext];    
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Employee" 
                                                     inManagedObjectContext:moc];

NSFetchRequest *request = [[[NSFetchRequest alloc] i开发者_如何学Cnit] autorelease];
[request setEntity:entityDescription];
// Set example predicate and sort orderings...
NSNumber *minimumSalary = ...;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(lastName LIKE[c]'Worsley') AND (salary > %@)", minimumSalary];    
[request setPredicate:predicate];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName" 
                                                               ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];
NSError *error;
NSArray *array = [moc executeFetchRequest:request error:&error];
if (array == nil){
    // Deal with error...
}


When you autorelease, you're basically saying: "I don't need this any longer, but anyone else is free to pick it up (before the auto release pool is drained)". When you explicitly relase an object you're saying: "I don't need this any longer and unless anyone else has already said otherwise (acquired), it should be deallocated immediately."

Consequently, autorelease is not normally the wrong thing to. It is required when you want to pass objects back to the sender of a message without requiring the sender to take care of releasing the object.


To Autorelease or Not to Autorelease

That is the question.

Whether tis nobler for the coder to suffer the slings and arrows of memory leaks or take arms against a sea of deferenced pointers and by retaining them, end them... Tis a consummation devoutly to be wished! Aye, there's the rub! ... For in those over released objects, what crashes may come when we reference objects that are not there must give us pause.

I couldn't help myself. I'll take the rep hit. I regret nothing!


The request object is going to be returned to the caller, whereas the sortDescriptor is being used and then discarded.

The rationale for autorelease is simple. Without it, any object returned from a function would need to be released by the caller if they didn't need it. Using autorelease means that functions may return an object which if the caller doesn't care about, or if they are going to look at it but not keep a reference to it, then they can just use it without adding additional code to free it. Only if they're keeping a reference do they need to retain it.

It's worth thinking about exactly what autorelease means. When you call autorelease on an object, it adds the object to a list, and when your application loop finishes, it'll have release called on it. This makes autorelease exactly equivalent to a delayed release.

The apple document on memory management is excellent and worth careful reading. http://developer.apple.com/iPhone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html


The question is this: how does the use of autorelease or release affect the lifetime of an object?

In both of your examples it makes no difference.

Both NSFetchRequest and NSSortDescriptors will be alive until the end of the method, regardless of whether they're released or autoreleased.

If you create an instance of an object and then give it to another object (say, an NSArray), it will remain alive regardless of whether you call release or autorelease.


Both retain and autorelease, functionally retain an object but they don't merge. The differences is that retain counts can only be decremented by another object whereas autoreleased counts are decremented automatically when the NSAutoreleasePool is drained. If no other object has retained the autoreleased object by the time the pool drains, it goes poof.

Basically, you use autorelease when you want to make sure an object hangs around in the current method and can be passed to other objects but you don't want to have to track its release yourself.

In your example code, autorelease is just a safety measure. The NSPredicate object is released because its job is finished but the coder wanted to make sure that the NSFetchRequest object hung around. You don't have to use "autorelease" in this instance but if you lost count of your releases the fetchRequest might vanish. On the other hand, you don't want it orphaned and leaking so you use autorelease to clean up when the pool the object is in drains.

The most common use of autorelease is when you are creating a variable number of objects each time. You don't want to have to track them all so you autorelease them and let the pool take care of them. (Even better, you create a local pool and drain it as soon as your done.)

In the Apple API standard, any method that creates a new object without the key words 'init','new' or 'create' returns an autoreleased object.

-[NSString initWithString:] is not autorelease but -[NSString stringWithString:] is. This causes problems in non-Garbage collection environments because stringWithString: returns a string that appears to behave like a retained object but later it will suddenly vanish seemingly at random when the autorelease pool it was created in drains.


Edit01: From the Apple Docs

An autorelease pool is an instance of NSAutoreleasePool that “contains” other objects that have received an autorelease message; when the autorelease pool is deallocated it sends a release message to each of those objects. An object can be put into an autorelease pool several times, and receives a release message for each time it was put into the pool. Thus, sending autorelease instead of release to an object extends the lifetime of that object at least until the pool itself is released (the object may survive longer if it is retained in the interim).

The retain counts and autorelease both keep an object alive by the same basic (but separate) count mechanism. The major difference is which owning object sends the release. With retained counts, its another object but for an autoreleased count its the autorelease pool.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜