Reputation: 26223
I am just curious with regards to the following, when I am writing code I always try and manage the memory myself by sticking to non-autoreleased objects. I know that this means that objects are not hanging around in the pool, but I was just curious if doing it this way in general is good practice or simply overkill?
// User Managed Memory
NSSet *buttonSizes = [[NSSet alloc] initWithObjects:@"Go", @"Going", @"Gone", nil];
[barItemLeft setPossibleTitles:buttonSizes];
[barItemRight setPossibleTitles:buttonSizes];
[buttonSizes release];
.
// Autoreleased Memory
NSSet *buttonSizes = [NSSet setWithObjects:@"Go", @"Going", @"Gone", nil];
[barItemLeft setPossibleTitles:buttonSizes];
[barItemRight setPossibleTitles:buttonSizes];
Upvotes: 5
Views: 392
Reputation: 243146
Total overkill. If you read the relevant documentation carefully, it does not say that you should avoid autoreleasing objects. It says that you should avoid using autorelease pools when you in tight, object-rich loops. In those cases, you should be managing your memory explicitly (with retain
and release
) to ensure that objects are created and destroyed in an amortized manner.
The argument that the iPhone is a memory-constrained environment is true, but a complete red herring. Objective-C, with the Foundation and Cocoa frameworks (though they weren't called that at the time), ran just fine on a NeXTcube, which had 16MB of RAM (expandable to 64). Even the iPhone 3, which is pretty much EOL at this point, has 128MB.
edit
Since an iPhone app is a runloop-based application, a new autorelease pool is going to be created and destroyed every time it spins. This is clearly defined in the documentation. As such, the only reasons you'd have to create your own autorelease pool are:
However, in the second case, you're recommended to explicitly manage memory as much as possible. This is so that your operation doesn't come to a screeching halt when it attempts to drain a pool with a few thousand objects in it. If you manage your memory manually, you can release these objects gradually as they are no longer needed, instead of saving them up for a single all-at-once release. You could help amortize the all-at-once release by nesting ARPools, which will help.
At the end of the day, though, just do what feels natural, and then (and only then) optimize it if you have concrete evidence that you need to do so.
edit #2
OK, it turns out that there is a recommendation to avoid using autorelease
. BUT that recommendation is in the "Allocate Memory Wisely" section of the "Tuning for Performance and Responsiveness" area of the iOS Application Programming Guide. In other words, avoid it if you're measuring a performance problem. But seriously: autorelease has been around for ~20 years and did just fine on computers far slower and more constrained than the iDevices of today.
Upvotes: 8
Reputation: 38012
Unless you see performance issues (or memory issues), I wouldn't worry about using the autorelease pools. Furthermore, autorelease in theory can be more performant than non-auto release. The really dangerous places to use autorelease is in large loops (for example, when importing a large data set). In these cases you can run out of the limited iPhone memory.
I'd recommend you only focus on removing autorelease usage once you've finished your application and can identify memory management issues using the built in instruments.
Upvotes: 3
Reputation: 5057
I think there is only one resonable answer: usually autorelease is not an performance issue. It is good to keep in mind that it could be problematic in tight loops, but unless a performance meter like Instruments shows a memory spike you have to get rid of, I would use it if you like.
Premature optimization is a great way of spending time for nothing. Maybe in the end you know that your solution is elegant, but it could be that the easier solution performs just as fine.
Upvotes: 1
Reputation: 237030
There's a balance. It depends a lot on the situation. In that particular case, assuming the barItem*
variables are long-lived ivars, avoiding autorelease is pretty close to 100% pointless, because the set will be sticking around regardless of whether you release it now or two seconds from now.
In fact, in most cases, it makes little difference whether objects are released now or on the next iteration of the runloop, because the runloop is going so fast that it's actually capable of creating smooth animation. The iPhone is a particularly memory-starved platform, so it's good not to leave things alive too long. But at the same time, be realistic: One autoreleased NSNumber in a method that's called every couple of seconds isn't even going to make a dent in your app's profile. Even 100 thousand-character NSStrings will only use about 0.065% of the system RAM on an iPhone 3GS. That only becomes significant when you build up a ton of them in a very short time. So if there's no problem, don't sweat it.
Upvotes: 1
Reputation: 2214
It depends on whether or not an autorelease pool is in place. For instance, if you're using objective-c objects in an AudioUnit's render callback (which is called from a separate thread without an autorelease pool) your autoreleased objects will leak. In this case it's important that you release them manually, or wrap them in an autorelease pool.
In general though, I think it's up to you and your coding style
Upvotes: 1
Reputation: 3300
When possible I like to use the autorelease methods. It eliminates the chance that I forget to release them or somebody comes in and changes the flow of the code so that the explicit release is bypassed. I vote that self-managing the releases is overkill.
Upvotes: 2