When I've created an UIImageView, I can see its memory allocation in the debugger.
But I can't find its image property, which supposedly holds the actual image, in the debugger.
The 2 structures under the UIImageview in debugger are:
UIView
_storage
How can I otherwise tell, that a UIImageView actually contains an image?
Cheers
Kevin
Didn't know if you can check for UIImageView image in debugging
But you can check anywhere in your code by putting the line :
If(UIImageView.Image == nil )
Maybe this helps
You can use GDB command:
po [yourImageView image]
_storage - it is also a pointer to UIImage, i.e. your image property within UIImageView object
Related
How am I able to automatically load and run a GIF using UIImageView?
I have imported each image individually but now sure where to go from here.
Also it is to be executed in viewDidLoad, not by using an IBAction of any kind.
I don't know if UIImageView supports gif format but you can give bunch of image to UIImageView and it shows them in order. Here is how:
let imageView = UIImageView()
imageView.animationImages = imageArray // imageArray is array of UIImage instances
There is bunch of other properties and methods that control this behavior in UIImageView. You can find more information in documentation
i´ve created a little game in which images are loaded when the user is touching the screen while moving. It depends on the screen position to load different images immediately.
I´ve got an UIImageView and because within the "touchesMoved" function, i´m loading the different images like this:
imageView.image = [UIImage imageNamed: [photos objectAtIndex: newImage ] ] ;
Now i want to improve my memory management using Instruments with "Allocations" & "Memory Monitor". Here´s i´m setting different snapshots with "Mark Heap" points and look for leaks. The line above is highlighted and now i want to know what´s wrong with it.. How can i improve that image-loading (without caching)?
Read this Dispelling the UIImage imageNamed: FUD
and also read the links in the question as well. Should answer everything you need.
First of all: imageNamed: does cache images.
If you're getting this line highlighted then there are 2 possible reasons (or both):
you're not properly releasing imageView
you're not properly releasing the photos array
+imageNamed returns an autoreleased object, yet the #property image in UIImageView retains it through its use until overwritten. -objectAtIndex: must return an object with a retain count of 1 which is not released.
If that indeed is the problem then the fix is
imageView.image = [UIImage imageNamed: [[photos objectAtIndex: newImage ] autorelease]];
However I doubt that is the real issue here.
basically im running my apps with instruments and found out that by just setting a background image to the UIButton, it takes up 6mb of data(which i do not want in case low-memory warnings). i read around and found out that since the button has been assigned the image, it retains it(and the memory).
How should i code it then?My current codes are as below. Btw im new to iPhone development so please tell me what to do.
btw this button would just bring me to another view. is there anyway to release the memory that was allocated to this image?
.m file
-(void)viewDidLoad{
UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"MainScreen.png"]];
selectionScreen.backgroundColor = background;
[background release]
}
You mentioned in comment above that your .png is under 300k. That's perhaps a touch big, but you're actually not looking at the right thing. A png gets expanded to a native CGImage object. I usually figure a 32-bit image with alpha takes up width * height * 4 bytes of memory. That's pretty much guaranteed to be bigger than the PNG it gets expanded from, and in your case could be quite big indeed. Enough so that the docs recommend not instantiating UIImages bigger than 1024 x 1024.
Now, one solution could be that -initWithPatternImage can take a small piece of your background, and will tile it when it's drawn. So your first shot at solving this would be to provide that method as small an image as possible, and let it tile to bigger sizes.
Second thing, the retention. You're correctly releasing your UIColor object after setting it on the background. You WANT that object you set it on to retain it! In a world of infinite memory, you'd want that button to retain its background color until the viewcontroller it's on gets dealloc'ed. If it's still huge and you really have to get rid of it before backing out of the view controller (say when you push to a new UINavigationController view or something), you could try setting background to nil (or a system default color maybe) in -viewDidDisappear and re-building your background in -viewWillAppear.
Wheb viewWillDisappear, you can set backgroundColor as another color, and release the background color you made.
-(void)viewWillDisappear:(BOOL)animated
{
// release original backgroundColor
// default backgroundColor is nil by UIView class reference.
selectionScreen.backgroundColor = nil;
}
Hope this can help you.
Did you try using something like:
button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:/frameOfChoice/];
[button setBackgroundImage:[UIImage imageNamed:#"MainScreen.png"] forControlState:UIControlStateNormal];
I'm not sure how this effects the memory usage tho.
I've got a fairly simple app that has the following in the view the program is mostly in:
int currentPageIndex;
NSArray *images;
NSString *nextImage;
IBOutlet UIImageView *firstPage;
IBOutlet UIButton *bigButton;
In the implementation viewDidLoad, I load the array with a bunch of image file names:
images = [NSArray arrayWithObjects:#"image1.jpg", #"image2.jpg", etc, nil];
[images retain];
Each time the bigButton is tapped, the image changes:
- (IBAction)bigButtonTapped:(id)sender {
currentPageIndex++;
nextImage = [images objectAtIndex:currentPageIndex];
firstPage.image = [UIImage imageNamed:nextImage];
}
Everything works as I want it to, except that I am getting a "Received memory warning. Level=1" in the console with my device plugged in. This warning comes up after every 12 images or so, and eventually it crashes with "EXC_BAD_ACCESS"
I thought this would actually be a good way not to put anything in memory, as there is only one UIImageView on the screen and its image is changed as I need it to be.
It is a very simple app so I'm sure the fix is very simple... any ideas what I might be overlooking? Thanks so much!!
Since you get a memory warning, the problem must be that the images aren't released. However, in the code you show, you're handling the images correctly. So the problem is most likely in a part of the code you're not showing us.
The only minor problem is see, which has been mentioned before, is that the currentPageIndex will eventually point outside of the range of the array. But this will cause a different error.
To avoid going over the size of the Array,
currentPageIndex= 0;
for(currentPageIndex in images){
doStuff;
}
OH!!!!! I THINK I spotted the your problem. Whenever you use UIImage imageNamed to load images all the images stay in memmory even though release reference to it. use the other UIImage method:contentOfFile.
One other thing, make sure your images are optimize for iOS. Use .png when posibible.
dibu2z
I assume Image is a retained property.
Try to release it at the beginning of your bigButtonTapped.
Hope it helps.
Could be that you've reached the end of the array and you're trying to access past the end of the array. You could do a
currentPageIndex++;
if ( currentPageIndex < [images count]) {
nextImage = [images objectAtIndex:currentPageIndex];
firstPage.image = [UIImage imageNamed:nextImage];
}
Also could be that the image you listed doesn't exist in the bundle.
There isn't really enough information here to say for sure what your problem is. EXC_BAD_ACCESS generally happens when you try to access an objects that has already been deallocated.
The quickest way to track down the real cause of EXC_BAD_ACCESS is by using the NSZombieEnabled executable argument, and then setting a breakpoint on objc_exception_throw. This will get you a stack trace, and allow you to determine specifically which object you are trying to access.
http://www.cocoadev.com/index.pl?NSZombieEnabled
Using Malloc to debug
I currently have this code:
UIImage *image = [[UIImage alloc] initWithContentsOfFile:[imagesPath stringByAppendingPathComponent:[NSString stringWithFormat:#"/%#.png", [postsArrayID objectAtIndex:indexPath.row]]]];
It's loading in an image to set in a UITableViewCell. This obviously leaks a lot of memory (I do release it, two lines down after setting the cells image to be that image), and I'm not sure if it caches the image at all.
Is there another way, that doesen't leak so much, I can use to load in images multiple times, like in a tableView, from the Documents-directory of my app? Thanks.
The leaks tool or Instruments should tell you what exactly is leaking. However, the image and imageView properties retain their images, so you may need to ensure you're properly releasing them in the dealloc method for the UITableViewCell. But like AngeDeLaMort said, we really need more information to give you a precise answer.
What is leaking exactly?
If you alloc an image and release it after, I don't see the leak your are talking about? Maybe more code or more precision would help.