Is it ok to never release a object? - iphone

In my iOS OBJC app, i use a object, specifically a UIImage. I always need this UIImage, specially when the user decides to switch orientations. The problem is I only get this image once and will need it for as long as the app runs. As a result, I have allocted this object and sent it a retain. I never release it, because if I do and the user switches orientation, that object could be realsed and I won't be able to do what I need to do and as a result the app will crash.
My Point: What do I do? Is what I'm doing bad because it creates a leak? And if so, how can I fix this?
Thanks.

It sounds like you're loading a single image once and keeping it around to reuse forever. That is perfectly fine, although if it's a large image that might not be needed constantly you might want to listen for memory notifications and release it then.
Problems with never releasing come in when you allocate large objects or large numbers of objects that are never released. Particularly if you continually re-allocate new instances of the "same" thing because you lose track of the old ones.

John. I have a different approach, load and release everywhere. You see, when you use [UIImage imageNamed:] then iOS caches the image. Next time you call [UIImage imageNamed:], it uses the cached image, from memory, very quickly. That way you can still code for clean memory (release all over the place, no retain) and iOS has your back.

Related

Memory leak in UIImagePicker in iphone

In my app user can take as may picture from camera, so after three time taking the picture it crashed. I can't resize the image (its requirement). So is there any other way to avoid memory leak.
Thanks
There is a know issue with the uiimagepickercontroller with memory leaks.
Apple recommend that you only allocate and instantiate only one instance and store it somewhere for the life of the application (whilst running that is).
Don't create a new one, use it and deallocate it each time you want to
use the control. If you do, your memory usage will keep increasing
until it crashes your app.
Personally I store it as a property in the appDelegate, but there may be a better way of doing it.
Edited: Thanks to CharlieMezak. Yes, such a leak might cause a crash. You'd better do some checking based on CharlieMezak's suggestions.
What may also cause crash is your code trying to access a piece of memory that was deallocated already.
I suggest you first check your code to see if there is any autorelease object that was not taken care of.
Second, turn on NSZombieEnabled, and test your app. If it's indeed trying to access something that was already deallocated (Zombie), the console will show you.
Third, and most importantly, post your crash report and part of the code that might be responsible for such a crash. Your description is somewhat vague, we need to see the report.
It sounds like your app is able to handle the photos correctly (from the user's perspective) two times, but on the third time it crashes. Sounds to me like a memory leak.
If it were a logical error in the code, or an attempt to access a deallocated object, the crash would probably occur the first time you take a photo.
It sounds like you're leaving the images in memory, so by the time you take your third photo, you're out of memory because the first two are still sitting there. Make sure you're releasing what you retain, and if you continue to have trouble, post your code!

Memory [ Real RAM ] used by App on IPhone 4.0 on lauch and then using UIImageview

I have two queries
I was running a sample app which having single view controller in it implemented. When I check the memory using Instrument it was showing 3.66 MB
. Wondered why it is taking so much of RAM as there is nothing much heavy in app.
When I have added UIImageview with the Image having size of 25 KB,then Memory uses go to 4.24 MB
[ I come to know the reason behind is "image is unpacked 320*480*4 = 580 KB" but need to debug more on this & it remains in cache ]
Along this I have also observed two scenarios
When we uses api [UIImage imageNamed:aName] for loading image, then calling [UIImageview release] doesn't have any effect.
But When we use
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:aName ofType:nil]];
Some memory is cleaned up when I call [UIImageview release]
In my app , I am going to use lot of images and that will cause a low memory and will crash the app.
Please provide me some ref or path to analyse why this behavior.
Thanks,
Sagar
Trying to fit your app in memory is a losing game. It'll lead you down weird paths of trying to figure out which sort of device you're running on, swapping in and out resources based on that, etc, etc.
The better option is to design your memory structure for ditchability, and then support a fairly harsh ditching regimen when you're notified of low memory conditions. Go ahead and use memory--it's there for that--and let the low memory warning be your signal to prune out unused resources.
A lot of people seem to feel bad that their application generates memory warnings. That's silly. The design pattern here is, eat all you want, but respond appropriately when you're told you're overweight. Given you're running on a broad range of devices with a broad range of memory profiles (an iPhone 3G has 1/4 the RAM of an iPhone 4 for instance), the best way is just to be sensitive to when you've filled memory.
The main hurdle you'll encounter is recovering from having ditched data. I find what works best is to explicitly set UIImage objects to nil, and then test for nil before using them, reloading them from the bundle or the network or whatever if necessary.
All that said: [UIImage imageNamed:] supports ditchability, but you don't have control over it. When a UIViewController subclass gets a memory warning, it will ditch cached UIImages that you've created with that method, but nothing you can do will make them go away until then. Even assigning a tiny something to the UIImage in question won't help because it's cached associated with the "name" that it's "Named", not the object that it is assigned to. So that method is good for images you're going to reuse a lot, but even so, it will get pruned when the time comes, and you need to respond appropriately.
Images, loaded with imageNamed, are cached in memory by UIKit, and images, loaded with imageWithContentsOfFile are not.

If I CFRelease() an image in core data, how do I get it back?

My iphone app plays a slide show made up of 5 user images.  These images are stored using core data.  I was noticing that memory was building up every time a different slide show was played and it was not releasing any of the previously played slide shows.
 
These images are showing up in Object Allocations as CFData. So I tried releasing this data in the dealloc method
CFRelease(slideshow.image1);
CFRelease(slideshow.image2);
CFRelease(slideshow.image3);
CFRelease(slideshow.image4);
CFRelease(slideshow.image5);
This releases the previous slideshow great...BUT when I go back to view that same slideshow again, it crashes.
 
I am guessing that I need to alloc/init these images again, but I am not sure how?  Or maybe I should be managing this memory in a different way?
It sounds like you're CFRelease-ing data that you shouldn't, and since you're mucking around with the NSManagedObject, you inevitably get a crash when Core Data goes "WTF?"
By "it was not releasing" are you seeing a memory leak, or simple memory usage growth? If the former, then we'll need more information, especially if Core Data is leaking, you might need to file a bug report (which is unlikely). If the latter, then there's much you can do, since Core Data is in charge of its own memory management.
It's possible you could use a NSAutoreleasePool to optimize but I can't say more on that.

Would such assignment of image cause a memory leak?

- (void)viewDidLoad {
[super viewDidLoad];
landscape.image = [UIImage imageNamed:#"tenerife1.png"];
}
I assign a new UIImage to the image property of an UIImageView object. I am not sure if that would result in a memory leak?
No, it should not. The old image should be automatically released when you set the new one, and the "imageNamed" method uses autorelease, so you should be OK there.
hey take into account imageNamed has serious memory issues as you loose control over its cache - ie: once you are done with your image, you cannot reclaim that memory. a quick google search would let you know how many people have faced problems with imageNamed
i was at the apple iphone tech talks and the guy giving the presentation confirmed the same damn thing - he suggested using imageWithContentsOfFile instead of imageNamed
if you just have couple of small images, its fine otherwise use imageWithContentsOfFile even though its a bit slower - and implement your own caching logic - check this great link on how to do it here
It depends on how the image property is defined. If it's defined as retain or, I suppose, even copy, it should be fine. You'll end up trying to reference deallocated memory and crashing your program if it's defined as assign.
Not ordinarily, but it would depend on how you've defined landscape.image. See post above. Be careful with using a lot of these:
[UIImage imageNamed:#"tenerife1.png"];
Since there is a tendency for these images to fill up memory, without getting released.

iPhone Development - Lessons in memory management

I need lessons in memory management. I have an application that uses multiple views (around 10), some of these are attached to tab controller. Problem is that I'm using images (many images that I load from a web service). I'm facing the following issues.
The memory keeps increasing when I scroll in the table view (why?) - I checked the CustomTableViewCell application from Apple's site, and it's showing the same signs when I run it with Instruments.
I'm using autorelease with many objects, but I see that these objects don't actually get released and the memory is wired. How can I get rid of these objects?
How can I tell the NSAutoreleasePool to periodically release the objects that are not being used? I think this can help me get rid of wired memory. But can I do that?
Is there any example by Apple or someone else (book or online articles) explaining how to use Instruments (in a little detail with example?) and to fine tune the application for memory and performance?
Thanks.
Now that we have the "just say no" answers to autorelease out of the way, I thought I'd add a tip on how to use autorelease more effectively. For better or worse not everyone's going to completely avoid autorelease-- if for no other reason than because Apple provides so many convenience methods that hand you autoreleased objects.
You can't just tell the autorelease pool to free up any objects that you're not using. There's no garbage collection, and how else is it going to know?
What you CAN do is to create a local autorelease pool and then release that when you no longer need the local autoreleased objects. If you have a block where you're creating autoreleased objects, you'll ensure they get freed by creating a local autorelease pool at the start of the block (just alloc/init it, no magic required) and then releasing the pool at the end of the block. And voila, and objects in the pool are also released.
Autorelease pools nest, so keep that in mind if you do this. If you release an autorelease pool, make sure it's the most-recently-allocated pool and not some other one.
The autoreleased memory is released when control is returned back to the system, but only when it chooses to. If you wish to force memory to be released use "release" which works there and then.
It should be noted that because of memory fragmentation that allocating and deallocating a block of memory may not seem to get you back to where you started in terms of measurable "free" memory.
Tony
For performance reasons, Apple recommends that you retain/release objects yourself whenever possible. autoreleasing them can cause excess memory usage as the autoreleased objects aren't always released immediately.
In other words, if you know you're done with an object, explicitly release it.
The UITableView has a way to reuse table cells that aren't being displayed anymore. That way if you only display 6 cells on the screen at once it doesn't keep on creating more as you scroll, but reuses the cells that have gone off screen. whenever you want to create a new cell, first query the tableview to see if it has any to reuse and if not then create a new one.
an example of this can be found on slide 55 of the standford iphone course note found here: http://www.scribd.com/doc/7671058/Standford-CS-193P-11Performance
According to Apple, you should not use autorelease and instead should retain and release objects explicitly as needed. autorelease will not release an object as soon as its function is over. If in the tableview you are using images downloaded from a webservice, try and cache these images and reuse them if possible. Another option is to only get those images which are being displayed.