I use instruments to see memory leaks. At least in one scenario where I am constantly flicking through slides/pages (inside UIScrollView) I don't see any memory leak. Using instruments - under "Al开发者_Go百科location lifespan" I switch to view "Created & Still Living" and see memory around 1.17MB throughout. I assume this means my app is using only this much actual memory and rest is being properly recycled.
Yet after flicking through 100 or so pages, I get a memory warning and then couple of my views are unloaded resulting in a crash of the whole app.
If I am not using a lot of memory and don't have memory leak why did I receive memory warning ? Since there is nothing I can really release I don't see a way to avoid the crash. Anyone experienced this situation or know what can I do ? Am I misinterpreting anything from Instruments ? Thanks much for any comment.
The documentation says:
If a matching image object is not already in the cache, this method loads the image data from the specified file, caches it, and then returns the resulting object.
Thus, every image you load by using imageNamed:
will continue to exist in the cache after you release your last ownership of it.
Instruments doesn't show this as a leak because, strictly speaking, it isn't one: Something (UIImage) still knows about these images. The Leaks instrument will only show a leak for an object that exists but nothing knows about.
You can still see this in Instruments, though.
Select the ObjectAlloc instrument in your trace document and sort the list of classes by current count, or by current total size. You'll see that the bulk of the memory is occupied by UIImage objects.
If you mouse over the class-name column for the UIImage row, you'll see a ➲ (go-to-iTunes-Store) icon; if you click on that, you'll see a list of all of your UIImage instances.
Then, if you mouse over the address column for an instance's row, you'll see the same button; this time, clicking on it will take you to the history of that address, including all creations, retentions, releases, and deallocations of objects with that address.
Here, you can see the image's allocation (within the UIImage class, ordered by you a few stack-frames down), retention (by you), and release (by you). You can also see that it has not been released by UIImage—the
+[UIImage imageNamed:]
cache still owns the image, hence the “leak”.
If you don't want images to pile up like that, load them yourself using imageWithContentsOfFile:
and the -[NSBundle pathForResource:ofType:]
method.
UPDATE: I have read that since iOS 3, UIImage will purge its cache in (at least some) low-memory situations, so this should not be as much of a “leak” as it used to be. You'll probably still see memory pile up, but then you should see the pile collapse eventually. If you still see memory piling up and can prove that it's Apple's fault, you should document your evidence and file a bug.
Do you have the NSZombieEnabled
environment variable set to yes? It will cause deallocated objects to persist in memory, thus not allowing you to regain the memory. So try to disable it, if active.
Have you checked you release all you IBOutlet objects? On your dealloc you should release any IBOutlet object you have in you object, even if they don't have a synthesize method.
We have a similar problem and we've solved it releasing all the IBOutlets.
Check this answer in Stack Overflow
If you only have 3 pages I understand that you are reusing some items.
Without the rest of the code it's difficult to say what's going wrong, but maybe you should try to release the cartoon object before creating a new one.
Try something like this:
IImage *image = [UIImage imageNamed:imageFile];
if (cartoon!=nil)
[cartoon release];
cartoon = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320, 280)];
cartoon.image = image ;
cartoon.backgroundColor = [UIColor brownColor];
Found the source of the problem. It is in the following snippet
UIImage *image = [UIImage imageNamed:imageFile];
cartoon = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320, 280)];
cartoon.image = image ;
cartoon.backgroundColor = [UIColor brownColor];
I have 100s of images plus some text on each page and user can scroll through them by finger flicking (just like they do in iphone's photo app). I only create 3 pages in my UIScrollView and load/unload (and also release) everything that I explicitly allocated. So when it comes to release the cartoon I simply release cartoon UIImageView and not the UIImage thinking it will be auto released.
But seems like it is not being auto released. My app gets a memory warning (I don't take any action) and OS unloads my views causing the crash.
When I comment out the two lines (modified snippet below), problem goes away. No warning no crash.
//UIImage *image = [UIImage imageNamed:imageFile];
cartoon = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320, 280)];
//cartoon.image = image ;
cartoon.backgroundColor = [UIColor brownColor];
Does anyone know how to workaround this issue ? Is there a way to force release memory from UIImage when warning happens ?
I recommend you to use KingFisher for caching your images its really really perfect library for photo caching
精彩评论