Reputation: 40641
With obj-c on the iPhone, is there any harm in autoreleasing everything instead of releasing?
Eg, this code:
NSString *recipe = [[NSString alloc] initWithUTF8String:sqlite3_column_text(dbps,0)];
[arr addObject:recipe];
[recipe release];
Can be shortened to two lines by autoreleasing the recipe nsstring when i create it:
NSString *recipe = [[[NSString alloc] initWithUTF8String:sqlite3_column_text(dbps,0)] autorelease];
[arr addObject:recipe];
Are there any drawbacks to this? I find it suits my coding style better. Thanks all.
Upvotes: 2
Views: 180
Reputation: 33592
I'll turn the question around: The main disadvantage with release
is that it's very easy to forget. Assignment to a local or to an instance variable look pretty much identical (they're entirely identical if you don't assign in an initializer):
Foo * a = [[Foo alloc] init];
myFoo = [[Foo alloc] init];
This, and similar issues, leads to a bunch of potential problems:
Personally, the overhead of a memory leak when you refactor code is worse than the overhead of a few autoreleased objects. I occasionally refactor code so it looks like this:
FooView * v = [[[FooView alloc] initWithFrame:CGRectZero] autorelease];
// set up v...
myFoo = [v retain];
For completeness, if you're doing a bunch of things in a loop (e.g. test code), you can autorelease at the end of every iteration with something like this:
for (size_t n = 100000; n--; ) {
NSAutoreleasePool * pool = [NSAutoreleasePool new];
// ... allocate and autorelease some stuff ...
[pool release]; pool = nil;
}
If you're worried about efficiency, you can gain significant speedups using (e.g.) CFString functions — the Objective-C overhead is pretty significant for small strings.
Upvotes: 1
Reputation: 783
Problem is when you do autorelease you're not actually releasing the object but adding it to the current autorelease pool. Object will be effectively released when you release that pool which is done every time through the main loop .
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
You can create you're own autorelease pool but I'm not sure it would be better than simply use release.
Upvotes: -2
Reputation: 22767
Here is my understanding on the subject, I'm sure I'll get downvoted to death if I say anything wrong ;)
init
+ release
will be faster than autorelease
. Most of the time performance is not an issueautorelease
at all times. If you want an object to stick around, you'll need to manually release
or stick your autoreleased obj in a property with a retain
so that you can get at it later otherwise your obj will be released as soon as it goes out of scopeinit
+ release
you have more fine grained control over what is happening, this may be useful for advanced multi-threaded scenarios (especially now that GCD is pervasive)autorelease
is probably fine most of the time so long as you understand how reference counting works, but do not treat it like a silver bullet. You can still leak plenty of memory using autorelease
incorrectly.Upvotes: 1
Reputation: 9212
If the object does not have a scope outside the function it is used, you should always release it in order to minimize the amount of memory consumed by your application.
If you let the object stick around until the autorelease pool kicks in, a lot of unneeded memory may need to be allocated. This is especially important with iOS 4 and fast app switching, where memory is also allocated to apps in the background.
The lower your own memory footprint is, the bigger a chance there is that your application will not be terminated when in the background in case memory gets tight.
Upvotes: 2
Reputation: 135548
The drawback is that the objects get released later. In most cases this won't be a problem but if you allocate and autorelease thousands of objects in a tight loop this overhead can add up to a point where it impacts performance or even causes your app to run out of memory.
In any case, you might want to use:
[NSString stringWithUTF8String:sqlite3_column_text(dbps,0)];
instead of
[[[NSString alloc] initWithUTF8String:sqlite3_column_text(dbps,0)] autorelease];
Upvotes: 6